Version Description
- Free edition of 3.0 pro release
Download this release
Release Info
Developer | soflyy |
Plugin | Import any XML or CSV File to WordPress |
Version | 3.0 |
Comparing to | |
See all releases |
Code changes from version 2.14 to 3.0
- actions/admin_menu.php +6 -6
- actions/admin_notices.php +4 -2
- actions/wp_loaded.php +1 -3
- classes/chunk.php +358 -0
- classes/download.php +39 -0
- classes/helper.php +10 -7
- config/options.php +2 -1
- controllers/admin/import.php +762 -609
- controllers/admin/manage.php +233 -52
- controllers/admin/settings.php +135 -5
- controllers/controller/admin.php +24 -13
- helpers/get_file_curl.php +90 -0
- helpers/import_custom_meta_box.php +29 -0
- helpers/pmxi_functions.php +285 -0
- libraries/XmlImportCsvParse.php +84 -1281
- libraries/XmlImportParser.php +13 -3
- libraries/XmlImportTemplateCodeGenerator.php +59 -61
- libraries/XmlImportTemplateParser.php +12 -61
- libraries/ast/XmlImportAstSpintax.php +2 -5
- libraries/pclzip.lib.php +5697 -0
- models/file/record.php +11 -5
- models/import/record.php +618 -565
- plugin.php +138 -22
- readme.txt +41 -26
- schema.php +16 -2
- screenshot-1.png +0 -0
- screenshot-2.png +0 -0
- screenshot-3.png +0 -0
- screenshot-4.png +0 -0
- static/css/admin.css +497 -36
- static/img/loading.gif +0 -0
- static/img/loading.png +0 -0
- static/img/progress_animated.gif +0 -0
- static/js/admin.js +164 -19
- static/js/jquery/css/redmond/images/animated-overlay.gif +0 -0
- static/js/jquery/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- static/js/jquery/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100_1.png +0 -0
- static/js/jquery/css/redmond/images/ui-bg_flat_55_fbec88_40x100.png +0 -0
- static/js/jquery/css/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png +0 -0
- static/js/jquery/css/redmond/images/ui-bg_glass_85_dfeffc_1x400.png +0 -0
- static/js/jquery/css/redmond/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- static/js/jquery/css/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
- static/js/jquery/css/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png +0 -0
- static/js/jquery/css/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
- static/js/jquery/css/redmond/images/ui-icons_217bc0_256x240.png +0 -0
- static/js/jquery/css/redmond/images/ui-icons_2e83ff_256x240.png +0 -0
- static/js/jquery/css/redmond/images/ui-icons_469bdd_256x240.png +0 -0
- static/js/jquery/css/redmond/images/ui-icons_6da8d5_256x240.png +0 -0
- static/js/jquery/css/redmond/images/ui-icons_cd0a0a_256x240.png +0 -0
- static/js/jquery/css/redmond/images/ui-icons_d8e7f3_256x240.png +0 -0
- static/js/jquery/css/redmond/images/ui-icons_f9bd01_256x240.png +0 -0
- static/js/jquery/css/redmond/jquery-ui.css +1177 -0
- static/js/jquery/jquery.mjs.nestedSortable.js +1 -1
- static/js/jquery/moment.js +6 -0
- static/js/plupload/plupload.flash.swf +0 -0
- static/js/plupload/plupload.full.js +2 -0
- static/js/plupload/plupload.silverlight.xap +0 -0
- static/js/plupload/wplupload.js +116 -0
- static/js/pmxi.js +1 -8
- views/admin/import/element_after.php +46 -27
- views/admin/import/evaluate.php +9 -4
- views/admin/import/index.php +83 -62
- views/admin/import/options.php +131 -375
- views/admin/import/options/_author_template.php +20 -0
- views/admin/import/options/_buttons_template.php +61 -0
- views/admin/import/options/_categories_template.php +53 -0
- views/admin/import/options/_custom_fields_template.php +43 -0
- views/admin/import/options/_featured_template.php +27 -0
- views/admin/import/options/_main_options_template.php +96 -0
- views/admin/import/options/_reimport_template.php +132 -0
- views/admin/import/options/_taxonomies_template.php +53 -0
- views/admin/import/process.php +92 -11
- views/admin/import/tag.php +7 -4
- views/admin/import/template.php +80 -69
- views/admin/manage/delete.php +4 -2
- views/admin/manage/index.php +56 -35
- views/admin/manage/update.php +1 -1
- views/admin/settings/index.php +2 -3
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 |
|
actions/admin_notices.php
CHANGED
@@ -2,13 +2,15 @@
|
|
2 |
|
3 |
function pmxi_admin_notices() {
|
4 |
// notify user if history folder is not writable
|
5 |
-
|
|
|
|
|
6 |
?>
|
7 |
<div class="error"><p>
|
8 |
<?php printf(
|
9 |
__('<b>%s Plugin</b>: History folder %s must be writable for the plugin to function properly. Please deactivate the plugin, set proper permissions to the folder and activate the plugin again.', 'pmxi_plugin'),
|
10 |
PMXI_Plugin::getInstance()->getName(),
|
11 |
-
|
12 |
) ?>
|
13 |
</p></div>
|
14 |
<?php
|
2 |
|
3 |
function pmxi_admin_notices() {
|
4 |
// notify user if history folder is not writable
|
5 |
+
$uploads = wp_upload_dir();
|
6 |
+
|
7 |
+
if ( ! is_dir($uploads['basedir'] . '/wpallimport_history') or ! is_writable($uploads['basedir'] . '/wpallimport_history')) {
|
8 |
?>
|
9 |
<div class="error"><p>
|
10 |
<?php printf(
|
11 |
__('<b>%s Plugin</b>: History folder %s must be writable for the plugin to function properly. Please deactivate the plugin, set proper permissions to the folder and activate the plugin again.', 'pmxi_plugin'),
|
12 |
PMXI_Plugin::getInstance()->getName(),
|
13 |
+
$uploads['basedir'] . '/wpallimport_history'
|
14 |
) ?>
|
15 |
</p></div>
|
16 |
<?php
|
actions/wp_loaded.php
CHANGED
@@ -2,8 +2,6 @@
|
|
2 |
|
3 |
function pmxi_wp_loaded() {
|
4 |
|
5 |
-
ini_set("max_input_time", PMXI_Plugin::getInstance()->getOption('max_input_time'));
|
6 |
-
ini_set("max_execution_time", PMXI_Plugin::getInstance()->getOption('max_execution_time'));
|
7 |
|
8 |
-
|
9 |
}
|
2 |
|
3 |
function pmxi_wp_loaded() {
|
4 |
|
|
|
|
|
5 |
|
6 |
+
|
7 |
}
|
classes/chunk.php
ADDED
@@ -0,0 +1,358 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Chunk
|
4 |
+
*
|
5 |
+
* Reads a large file in as chunks for easier parsing.
|
6 |
+
*
|
7 |
+
* The chunks returned are whole <$this->options['element']/>s found within file.
|
8 |
+
*
|
9 |
+
* Each call to read() returns the whole element including start and end tags.
|
10 |
+
*
|
11 |
+
* Tested with a 1.8MB file, extracted 500 elements in 0.11s
|
12 |
+
* (with no work done, just extracting the elements)
|
13 |
+
*
|
14 |
+
* Usage:
|
15 |
+
* <code>
|
16 |
+
* // initialize the object
|
17 |
+
* $file = new Chunk('chunk-test.xml', array('element' => 'Chunk'));
|
18 |
+
*
|
19 |
+
* // loop through the file until all lines are read
|
20 |
+
* while ($xml = $file->read()) {
|
21 |
+
* // do whatever you want with the string
|
22 |
+
* $o = simplexml_load_string($xml);
|
23 |
+
* }
|
24 |
+
* </code>
|
25 |
+
*
|
26 |
+
* @package default
|
27 |
+
* @author Dom Hastings
|
28 |
+
*/
|
29 |
+
class PMXI_Chunk {
|
30 |
+
/**
|
31 |
+
* options
|
32 |
+
*
|
33 |
+
* @var array Contains all major options
|
34 |
+
* @access public
|
35 |
+
*/
|
36 |
+
public $options = array(
|
37 |
+
'path' => './', // string The path to check for $file in
|
38 |
+
'element' => '', // string The XML element to return
|
39 |
+
'chunkSize' => 4096, // integer The amount of bytes to retrieve in each chunk
|
40 |
+
'type' => 'upload'
|
41 |
+
);
|
42 |
+
|
43 |
+
/**
|
44 |
+
* file
|
45 |
+
*
|
46 |
+
* @var string The filename being read
|
47 |
+
* @access public
|
48 |
+
*/
|
49 |
+
public $file = '';
|
50 |
+
/**
|
51 |
+
* pointer
|
52 |
+
*
|
53 |
+
* @var integer The current position the file is being read from
|
54 |
+
* @access public
|
55 |
+
*/
|
56 |
+
public $pointer = 0;
|
57 |
+
|
58 |
+
public $cloud = array();
|
59 |
+
|
60 |
+
/**
|
61 |
+
* handle
|
62 |
+
*
|
63 |
+
* @var resource The fopen() resource
|
64 |
+
* @access private
|
65 |
+
*/
|
66 |
+
private $handle = null;
|
67 |
+
/**
|
68 |
+
* reading
|
69 |
+
*
|
70 |
+
* @var boolean Whether the script is currently reading the file
|
71 |
+
* @access private
|
72 |
+
*/
|
73 |
+
private $reading = false;
|
74 |
+
/**
|
75 |
+
* readBuffer
|
76 |
+
*
|
77 |
+
* @var string Used to make sure start tags aren't missed
|
78 |
+
* @access private
|
79 |
+
*/
|
80 |
+
private $readBuffer = '';
|
81 |
+
|
82 |
+
/**
|
83 |
+
* __construct
|
84 |
+
*
|
85 |
+
* Builds the Chunk object
|
86 |
+
*
|
87 |
+
* @param string $file The filename to work with
|
88 |
+
* @param array $options The options with which to parse the file
|
89 |
+
* @author Dom Hastings
|
90 |
+
* @access public
|
91 |
+
*/
|
92 |
+
public function __construct($file, $options = array(), $pointer = 0) {
|
93 |
+
// merge the options together
|
94 |
+
$this->options = array_merge($this->options, (is_array($options) ? $options : array()));
|
95 |
+
|
96 |
+
// check that the path ends with a /
|
97 |
+
if (substr($this->options['path'], -1) != '/') {
|
98 |
+
$this->options['path'] .= '/';
|
99 |
+
}
|
100 |
+
|
101 |
+
// normalize the filename
|
102 |
+
$file_base = basename($file);
|
103 |
+
|
104 |
+
// make sure chunkSize is an int
|
105 |
+
$this->options['chunkSize'] = intval($this->options['chunkSize']);
|
106 |
+
|
107 |
+
// check it's valid
|
108 |
+
if ($this->options['chunkSize'] < 64) {
|
109 |
+
$this->options['chunkSize'] = 1024;
|
110 |
+
}
|
111 |
+
|
112 |
+
$this->pointer = $pointer;
|
113 |
+
|
114 |
+
// set the filename
|
115 |
+
$this->file = ($this->options['path'] != './') ? realpath($this->options['path'].$file_base) : $file;
|
116 |
+
|
117 |
+
// check the file exists
|
118 |
+
if (!file_exists($this->file)){
|
119 |
+
throw new Exception('File doesn\'t exist');
|
120 |
+
}
|
121 |
+
|
122 |
+
// open the file
|
123 |
+
$this->handle = fopen($this->file, 'rb');
|
124 |
+
|
125 |
+
// check the file opened successfully
|
126 |
+
if (!$this->handle) {
|
127 |
+
throw new Exception('Error opening file for reading');
|
128 |
+
}
|
129 |
+
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* __destruct
|
134 |
+
*
|
135 |
+
* Cleans up
|
136 |
+
*
|
137 |
+
* @return void
|
138 |
+
* @author Dom Hastings
|
139 |
+
* @access public
|
140 |
+
*/
|
141 |
+
public function __destruct() {
|
142 |
+
// close the file resource
|
143 |
+
fclose($this->handle);
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* read
|
148 |
+
*
|
149 |
+
* Reads the first available occurence of the XML element $this->options['element']
|
150 |
+
*
|
151 |
+
* @return string The XML string from $this->file
|
152 |
+
* @author Dom Hastings
|
153 |
+
* @access public
|
154 |
+
*/
|
155 |
+
public function read() {
|
156 |
+
// check we have an element specified
|
157 |
+
if (!empty($this->options['element'])) {
|
158 |
+
// trim it
|
159 |
+
$element = trim($this->options['element']);
|
160 |
+
|
161 |
+
} else {
|
162 |
+
$element = '';
|
163 |
+
}
|
164 |
+
|
165 |
+
// initialize the buffer
|
166 |
+
$buffer = false;
|
167 |
+
|
168 |
+
// if the element is empty, then start auto detect root element tag name
|
169 |
+
if (empty($element)) {
|
170 |
+
// let the script know we're reading
|
171 |
+
$this->reading = true;
|
172 |
+
$founded_tags = array();
|
173 |
+
// read in the whole doc, cos we don't know what's wanted
|
174 |
+
while ($this->reading) {
|
175 |
+
$c = fread($this->handle, $this->options['chunkSize']);
|
176 |
+
if ( preg_match_all("/<\\w+\\s*[^<]*\\s*\/?>/i", $c, $matches, PREG_PATTERN_ORDER) ){
|
177 |
+
foreach ($matches[0] as $tag) {
|
178 |
+
$tag = explode(" ",trim(str_replace(array('<','>','/'), '', $tag)));
|
179 |
+
array_push($founded_tags, $tag[0]);
|
180 |
+
}
|
181 |
+
}
|
182 |
+
$this->reading = (!feof($this->handle));
|
183 |
+
}
|
184 |
+
|
185 |
+
// we must be looking for a specific element
|
186 |
+
}
|
187 |
+
|
188 |
+
if (empty($element) and !empty($founded_tags)) {
|
189 |
+
|
190 |
+
$element_counts = array_count_values($founded_tags);
|
191 |
+
|
192 |
+
if (!empty($element_counts)){
|
193 |
+
|
194 |
+
$this->cloud = array_slice($element_counts, 0, 2);
|
195 |
+
|
196 |
+
foreach ($element_counts as $tag => $count) {
|
197 |
+
if ($count > 1 and empty($this->options['element'])) {
|
198 |
+
$this->options['element'] = $element = $tag;
|
199 |
+
}
|
200 |
+
elseif ($count > 1){
|
201 |
+
$this->cloud[$tag] = $count;
|
202 |
+
}
|
203 |
+
}
|
204 |
+
}
|
205 |
+
|
206 |
+
}
|
207 |
+
|
208 |
+
// return it all if element doesn't founded
|
209 |
+
if (empty($element))
|
210 |
+
return false;
|
211 |
+
|
212 |
+
// we must be looking for a specific element
|
213 |
+
//}
|
214 |
+
|
215 |
+
// initialize the buffer
|
216 |
+
$buffer = false;
|
217 |
+
|
218 |
+
// set up the strings to find
|
219 |
+
$open = '<'.$element;
|
220 |
+
$close = '</'.$element.'>';
|
221 |
+
|
222 |
+
// let the script know we're reading
|
223 |
+
$this->reading = true;
|
224 |
+
|
225 |
+
// reset the global buffer
|
226 |
+
$this->readBuffer = '';
|
227 |
+
|
228 |
+
// this is used to ensure all data is read, and to make sure we don't send the start data again by mistake
|
229 |
+
$store = false;
|
230 |
+
|
231 |
+
// seek to the position we need in the file
|
232 |
+
fseek($this->handle, $this->pointer);
|
233 |
+
|
234 |
+
// start reading
|
235 |
+
while ($this->reading && !feof($this->handle)) {
|
236 |
+
|
237 |
+
// store the chunk in a temporary variable
|
238 |
+
$tmp = fread($this->handle, $this->options['chunkSize']);
|
239 |
+
|
240 |
+
// update the global buffer
|
241 |
+
$this->readBuffer .= $tmp;
|
242 |
+
|
243 |
+
// check for the open string
|
244 |
+
$checkOpen = strpos($tmp, $open." ");
|
245 |
+
if (!$checkOpen) $checkOpen = strpos($tmp, $open.">");
|
246 |
+
|
247 |
+
// if it wasn't in the new buffer
|
248 |
+
if (!$checkOpen && !($store)) {
|
249 |
+
// check the full buffer (in case it was only half in this buffer)
|
250 |
+
$checkOpen = strpos($this->readBuffer, $open." ");
|
251 |
+
if (!$checkOpen) $checkOpen = strpos($this->readBuffer, $open.">");
|
252 |
+
|
253 |
+
// if it was in there
|
254 |
+
if ($checkOpen) {
|
255 |
+
// set it to the remainder
|
256 |
+
$checkOpen = $checkOpen % $this->options['chunkSize'];
|
257 |
+
}
|
258 |
+
}
|
259 |
+
|
260 |
+
// check for the close string
|
261 |
+
$checkClose = strpos($tmp, $close);
|
262 |
+
$withoutcloseelement = false;
|
263 |
+
if (!$checkClose){
|
264 |
+
$checkClose = (preg_match_all("/\/>\s*".$open."\s*/", $this->readBuffer, $matches)) ? strpos($this->readBuffer, $matches[0][0]) : false;
|
265 |
+
if ($checkClose)
|
266 |
+
$withoutcloseelement = true;
|
267 |
+
else{
|
268 |
+
/*$checkClose = (preg_match_all("/\s*\/>\s*<\/", $this->readBuffer, $matches)) ? strpos($this->readBuffer, $matches[0][0]) : false;
|
269 |
+
if ($checkClose)
|
270 |
+
$withoutcloseelement = true;*/
|
271 |
+
}
|
272 |
+
}
|
273 |
+
|
274 |
+
// if it wasn't in the new buffer
|
275 |
+
if (!$checkClose && ($store)) {
|
276 |
+
// check the full buffer (in case it was only half in this buffer)
|
277 |
+
$checkClose = strpos($this->readBuffer, $close);
|
278 |
+
|
279 |
+
$withoutcloseelement = false;
|
280 |
+
if (!$checkClose){
|
281 |
+
$checkClose = (preg_match_all("/\/>\s*".$open."\s*/", $this->readBuffer, $matches)) ? strpos($this->readBuffer, $matches[0][0]) : false;
|
282 |
+
if ($checkClose)
|
283 |
+
$withoutcloseelement = true;
|
284 |
+
else{
|
285 |
+
/*$checkClose = (preg_match_all("//>\\s*<\//", $this->readBuffer, $matches)) ? strpos($this->readBuffer, $matches[0][0]) : false;
|
286 |
+
if ($checkClose)
|
287 |
+
$withoutcloseelement = true;*/
|
288 |
+
}
|
289 |
+
}
|
290 |
+
// if it was in there
|
291 |
+
if ($checkClose) {
|
292 |
+
// set it to the remainder plus the length of the close string itself
|
293 |
+
if (!$withoutcloseelement){
|
294 |
+
$checkClose = ($checkClose + strlen($close)) % $this->options['chunkSize'];
|
295 |
+
}else{
|
296 |
+
$checkClose = ($checkClose + strlen("/>")) % $this->options['chunkSize'];
|
297 |
+
}
|
298 |
+
}
|
299 |
+
|
300 |
+
// if it was
|
301 |
+
} elseif ($checkClose) {
|
302 |
+
// add the length of the close string itself
|
303 |
+
if ( ! $withoutcloseelement)
|
304 |
+
$checkClose += strlen($close);
|
305 |
+
else
|
306 |
+
$checkClose += strlen("/>"); // "/>" symbols
|
307 |
+
}
|
308 |
+
|
309 |
+
// if we've found the opening string and we're not already reading another element
|
310 |
+
if ($checkOpen !== false && !($store)) {
|
311 |
+
// if we're found the end element too
|
312 |
+
if ($checkClose !== false) {
|
313 |
+
// append the string only between the start and end element
|
314 |
+
$buffer .= substr($tmp, $checkOpen, ($checkClose - $checkOpen));
|
315 |
+
|
316 |
+
// update the pointer
|
317 |
+
$this->pointer += $checkClose;
|
318 |
+
|
319 |
+
// let the script know we're done
|
320 |
+
$this->reading = false;
|
321 |
+
|
322 |
+
} else {
|
323 |
+
// append the data we know to be part of this element
|
324 |
+
$buffer .= substr($tmp, $checkOpen);
|
325 |
+
|
326 |
+
// update the pointer
|
327 |
+
$this->pointer += $this->options['chunkSize'];
|
328 |
+
|
329 |
+
// let the script know we're gonna be storing all the data until we find the close element
|
330 |
+
$store = true;
|
331 |
+
}
|
332 |
+
|
333 |
+
// if we've found the closing element
|
334 |
+
} elseif ($checkClose !== false) {
|
335 |
+
// update the buffer with the data upto and including the close tag
|
336 |
+
$buffer .= substr($tmp, 0, $checkClose);
|
337 |
+
|
338 |
+
// update the pointer
|
339 |
+
$this->pointer += $checkClose;
|
340 |
+
|
341 |
+
// let the script know we're done
|
342 |
+
$this->reading = false;
|
343 |
+
|
344 |
+
// if we've found the closing element, but half in the previous chunk
|
345 |
+
} elseif ($store) {
|
346 |
+
// update the buffer
|
347 |
+
$buffer .= $tmp;
|
348 |
+
|
349 |
+
// and the pointer
|
350 |
+
$this->pointer += $this->options['chunkSize'];
|
351 |
+
}
|
352 |
+
|
353 |
+
}
|
354 |
+
|
355 |
+
// return the element (or the whole file if we're not looking for elements)
|
356 |
+
return $buffer;
|
357 |
+
}
|
358 |
+
}
|
classes/download.php
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class PMXI_Download
|
4 |
+
{
|
5 |
+
|
6 |
+
static public function zip($file_name)
|
7 |
+
{
|
8 |
+
|
9 |
+
header('Content-type: application/zip');
|
10 |
+
header("Content-Disposition: attachment; filename=\"".basename($file_name)."\"");
|
11 |
+
readfile($file_name);
|
12 |
+
die;
|
13 |
+
}
|
14 |
+
|
15 |
+
static public function xls($file_name)
|
16 |
+
{
|
17 |
+
header("Content-Type: application/vnd.ms-excel; charset=UTF-8");
|
18 |
+
header("Content-Disposition: attachment; filename=\"".basename($file_name)."\"");
|
19 |
+
readfile($file_name);
|
20 |
+
die;
|
21 |
+
}
|
22 |
+
|
23 |
+
static public function csv($file_name)
|
24 |
+
{
|
25 |
+
header("Content-Type: text/plain; charset=UTF-8");
|
26 |
+
header("Content-Disposition: attachment; filename=\"".basename($file_name)."\"");
|
27 |
+
readfile($file_name);
|
28 |
+
die;
|
29 |
+
}
|
30 |
+
|
31 |
+
static public function xml($file_name)
|
32 |
+
{
|
33 |
+
header("Content-Type: application/xhtml+xml; charset=UTF-8");
|
34 |
+
header("Content-Disposition: attachment; filename=\"".basename($file_name)."\"");
|
35 |
+
readfile($file_name);
|
36 |
+
die;
|
37 |
+
}
|
38 |
+
|
39 |
+
}
|
classes/helper.php
CHANGED
@@ -36,25 +36,26 @@ class PMXI_Helper {
|
|
36 |
$split = explode('/', str_replace('\\', '/', $pattern));
|
37 |
$mask = array_pop($split);
|
38 |
$path = implode('/', $split);
|
39 |
-
|
|
|
40 |
$glob = array();
|
41 |
while(($file = readdir($dir)) !== false) {
|
42 |
// Recurse subdirectories (self::GLOB_RECURSE)
|
43 |
if (($flags & self::GLOB_RECURSE) && is_dir($path . '/' . $file) && ( ! in_array($file, array('.', '..')))) {
|
44 |
$glob = array_merge($glob, self::array_prepend(self::safe_glob($path . '/' . $file . '/' . $mask, $flags), ($flags & self::GLOB_PATH ? '' : $file . '/')));
|
45 |
}
|
46 |
-
// Match file mask
|
47 |
-
if (self::fnmatch($mask, $file)) {
|
48 |
if ((( ! ($flags & self::GLOB_ONLYDIR)) || is_dir("$path/$file"))
|
49 |
&& (( ! ($flags & self::GLOB_NODIR)) || ( ! is_dir($path . '/' . $file)))
|
50 |
&& (( ! ($flags & self::GLOB_NODOTS)) || ( ! in_array($file, array('.', '..'))))
|
51 |
) {
|
52 |
$glob[] = ($flags & self::GLOB_PATH ? $path . '/' : '') . $file . ($flags & self::GLOB_MARK ? '/' : '');
|
53 |
}
|
54 |
-
}
|
55 |
}
|
56 |
closedir($dir);
|
57 |
-
if ( ! ($flags & self::GLOB_NOSORT)) sort($glob);
|
58 |
return $glob;
|
59 |
} else {
|
60 |
return false;
|
@@ -95,6 +96,7 @@ class PMXI_Helper {
|
|
95 |
* non-POSIX complient remplacement for the fnmatch
|
96 |
*/
|
97 |
public static function fnmatch($pattern, $string, $flags = 0) {
|
|
|
98 |
$modifiers = null;
|
99 |
$transforms = array(
|
100 |
'\*' => '.*',
|
@@ -103,7 +105,8 @@ class PMXI_Helper {
|
|
103 |
'\[' => '[',
|
104 |
'\]' => ']',
|
105 |
'\.' => '\.',
|
106 |
-
'\\' => '\\\\'
|
|
|
107 |
);
|
108 |
|
109 |
// Forward slash in string must be in pattern:
|
@@ -130,7 +133,7 @@ class PMXI_Helper {
|
|
130 |
.strtr(preg_quote($pattern, '#'), $transforms)
|
131 |
.'$#'
|
132 |
.$modifiers;
|
133 |
-
|
134 |
return (boolean)preg_match($pattern, $string);
|
135 |
}
|
136 |
}
|
36 |
$split = explode('/', str_replace('\\', '/', $pattern));
|
37 |
$mask = array_pop($split);
|
38 |
$path = implode('/', $split);
|
39 |
+
|
40 |
+
if (($dir = @opendir($path)) !== false or ($dir = @opendir($path . '/')) !== false) {
|
41 |
$glob = array();
|
42 |
while(($file = readdir($dir)) !== false) {
|
43 |
// Recurse subdirectories (self::GLOB_RECURSE)
|
44 |
if (($flags & self::GLOB_RECURSE) && is_dir($path . '/' . $file) && ( ! in_array($file, array('.', '..')))) {
|
45 |
$glob = array_merge($glob, self::array_prepend(self::safe_glob($path . '/' . $file . '/' . $mask, $flags), ($flags & self::GLOB_PATH ? '' : $file . '/')));
|
46 |
}
|
47 |
+
// Match file mask
|
48 |
+
if (self::fnmatch($mask, $file)) {
|
49 |
if ((( ! ($flags & self::GLOB_ONLYDIR)) || is_dir("$path/$file"))
|
50 |
&& (( ! ($flags & self::GLOB_NODIR)) || ( ! is_dir($path . '/' . $file)))
|
51 |
&& (( ! ($flags & self::GLOB_NODOTS)) || ( ! in_array($file, array('.', '..'))))
|
52 |
) {
|
53 |
$glob[] = ($flags & self::GLOB_PATH ? $path . '/' : '') . $file . ($flags & self::GLOB_MARK ? '/' : '');
|
54 |
}
|
55 |
+
}
|
56 |
}
|
57 |
closedir($dir);
|
58 |
+
if ( ! ($flags & self::GLOB_NOSORT)) sort($glob);
|
59 |
return $glob;
|
60 |
} else {
|
61 |
return false;
|
96 |
* non-POSIX complient remplacement for the fnmatch
|
97 |
*/
|
98 |
public static function fnmatch($pattern, $string, $flags = 0) {
|
99 |
+
|
100 |
$modifiers = null;
|
101 |
$transforms = array(
|
102 |
'\*' => '.*',
|
105 |
'\[' => '[',
|
106 |
'\]' => ']',
|
107 |
'\.' => '\.',
|
108 |
+
'\\' => '\\\\',
|
109 |
+
'\-' => '-',
|
110 |
);
|
111 |
|
112 |
// Forward slash in string must be in pattern:
|
133 |
.strtr(preg_quote($pattern, '#'), $transforms)
|
134 |
.'$#'
|
135 |
.$modifiers;
|
136 |
+
|
137 |
return (boolean)preg_match($pattern, $string);
|
138 |
}
|
139 |
}
|
config/options.php
CHANGED
@@ -14,5 +14,6 @@ $config = array(
|
|
14 |
"max_execution_time" => -1,
|
15 |
"dismiss" => 0,
|
16 |
"html_entities" => 0,
|
17 |
-
"utf8_decode" => 0
|
|
|
18 |
);
|
14 |
"max_execution_time" => -1,
|
15 |
"dismiss" => 0,
|
16 |
"html_entities" => 0,
|
17 |
+
"utf8_decode" => 0,
|
18 |
+
"cron_job_key" => url_title(rand_char(12))
|
19 |
);
|
controllers/admin/import.php
CHANGED
@@ -12,22 +12,32 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
12 |
protected function init() {
|
13 |
parent::init();
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
// enable sessions
|
16 |
if ( ! session_id()) session_start();
|
17 |
|
18 |
if ('PMXI_Admin_Manage' == PMXI_Plugin::getInstance()->getAdminCurrentScreen()->base) { // prereqisites are not checked when flow control is deligated
|
19 |
$id = $this->input->get('id');
|
20 |
-
$this->data['import'] = $import = new PMXI_Import_Record();
|
21 |
if ( ! $id or $import->getById($id)->isEmpty()) { // specified import is not found
|
22 |
wp_redirect(add_query_arg('page', 'pmxi-admin-manage', admin_url('admin.php'))); die();
|
23 |
}
|
24 |
$this->isWizard = false;
|
25 |
|
26 |
} else {
|
27 |
-
$action = PMXI_Plugin::getInstance()->getAdminCurrentScreen()->action;
|
28 |
$this->_step_ready($action);
|
29 |
$this->isInline = 'process' == $action;
|
30 |
-
}
|
31 |
|
32 |
XmlImportConfig::getInstance()->setCacheDirectory(sys_get_temp_dir());
|
33 |
|
@@ -42,34 +52,38 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
42 |
public function get($var)
|
43 |
{
|
44 |
return $this->{$var};
|
45 |
-
}
|
46 |
|
47 |
/**
|
48 |
* Checks whether corresponding step of wizard is complete
|
49 |
* @param string $action
|
50 |
*/
|
51 |
-
protected function _step_ready($action) {
|
52 |
// step #1: xml selction - has no prerequisites
|
53 |
if ('index' == $action) return true;
|
54 |
|
55 |
// step #2: element selection
|
56 |
-
$this->data['dom'] = $dom = new DOMDocument();
|
57 |
$this->data['update_previous'] = $update_previous = new PMXI_Import_Record();
|
58 |
$old = libxml_use_internal_errors(true);
|
|
|
59 |
if (empty($_SESSION['pmxi_import'])
|
60 |
-
or ! $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $_SESSION['pmxi_import']['xml']))
|
61 |
-
or empty($_SESSION['pmxi_import']['source'])
|
62 |
or ! empty($_SESSION['pmxi_import']['update_previous']) and $update_previous->getById($_SESSION['pmxi_import']['update_previous'])->isEmpty()
|
63 |
) {
|
|
|
64 |
wp_redirect_or_javascript($this->baseUrl); die();
|
65 |
}
|
66 |
libxml_use_internal_errors($old);
|
67 |
if ('element' == $action) return true;
|
68 |
if ('evaluate' == $action) return true;
|
69 |
-
|
70 |
// step #3: template
|
71 |
$xpath = new DOMXPath($dom);
|
|
|
72 |
if (empty($_SESSION['pmxi_import']['xpath']) or ! ($this->data['elements'] = $elements = $xpath->query($_SESSION['pmxi_import']['xpath'])) or ! $elements->length) {
|
|
|
73 |
wp_redirect_or_javascript(add_query_arg('action', 'element', $this->baseUrl)); die();
|
74 |
}
|
75 |
if ('template' == $action or 'preview' == $action or 'tag' == $action) return true;
|
@@ -90,7 +104,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
90 |
*/
|
91 |
public function index() {
|
92 |
|
93 |
-
$import = new PMXI_Import_Record();
|
94 |
$this->data['id'] = $id = $this->input->get('id');
|
95 |
if ($id and $import->getById($id)->isEmpty()) { // update requested but corresponding import is not found
|
96 |
wp_redirect(remove_query_arg('id', $this->baseUrl)); die();
|
@@ -104,495 +118,283 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
104 |
'reimport' => '',
|
105 |
'is_update_previous' => $id ? 1 : 0,
|
106 |
'update_previous' => $id,
|
|
|
|
|
|
|
|
|
107 |
));
|
108 |
-
|
109 |
-
$this->data['imports'] = $imports = new PMXI_Import_List();
|
110 |
-
$imports->setColumns('id', 'name', 'registered_on', 'path')->getBy(NULL, 'name ASC, registered_on DESC');
|
111 |
-
|
112 |
$this->data['history'] = $history = new PMXI_File_List();
|
113 |
$history->setColumns('id', 'name', 'registered_on', 'path')->getBy(NULL, 'id DESC');
|
114 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
if ($this->input->post('is_submitted_continue')) {
|
116 |
if ( ! empty($_SESSION['pmxi_import']['xml'])) {
|
117 |
wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
|
118 |
}
|
119 |
-
} elseif ('upload' == $this->input->post('type')) {
|
120 |
-
|
|
|
|
|
|
|
121 |
$this->errors->add('form-validation', __('XML/CSV file must be specified', 'pmxi_plugin'));
|
122 |
-
} elseif (
|
123 |
$this->errors->add('form-validation', __('Uploaded file is empty', 'pmxi_plugin'));
|
124 |
-
} elseif ( ! preg_match('%\W(xml|gzip|zip|csv|gz)$%i', trim($
|
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($
|
127 |
-
|
128 |
-
|
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 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
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 |
-
}
|
210 |
else {
|
211 |
-
// delete file in temporary folder
|
212 |
-
unlink( $uploads['path'] .'/'. trim(basename($_FILES['upload']['name']) ));
|
213 |
-
$filename = $_FILES['upload']['tmp_name'];
|
214 |
-
|
215 |
-
// Let's make sure the file exists and is writable first.
|
216 |
-
if (is_writable($filename)) {
|
217 |
|
218 |
-
|
219 |
-
$this->errors->add('form-validation', __('Cannot open file ' . $filename, 'pmxi_plugin'));
|
220 |
-
}
|
221 |
-
|
222 |
-
// Write $somecontent to our opened file.
|
223 |
-
if (fwrite($handle, $xml) === FALSE) {
|
224 |
-
$this->errors->add('form-validation', __('Cannot write to file ' . $filename, 'pmxi_plugin'));
|
225 |
-
}
|
226 |
-
|
227 |
-
fclose($handle);
|
228 |
-
|
229 |
-
} else {
|
230 |
-
$this->errors->add('form-validation', __('The file' . $filename . 'is not writable', 'pmxi_plugin'));
|
231 |
-
}
|
232 |
-
$filePath = $_FILES['upload']['tmp_name'];
|
233 |
-
$source = array(
|
234 |
-
'name' => $_FILES['upload']['name'],
|
235 |
-
'type' => 'upload',
|
236 |
-
'path' => '',
|
237 |
-
);
|
238 |
-
}
|
239 |
-
} else {
|
240 |
-
$filePath = $_FILES['upload']['tmp_name'];
|
241 |
-
$source = array(
|
242 |
-
'name' => $_FILES['upload']['name'],
|
243 |
-
'type' => 'upload',
|
244 |
-
'path' => '',
|
245 |
-
);
|
246 |
-
}
|
247 |
-
} elseif ('url' == $this->input->post('type')) {
|
248 |
-
if (empty($post['url'])) {
|
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 |
-
|
263 |
-
|
264 |
-
|
|
|
|
|
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 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
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 |
-
|
317 |
-
|
318 |
-
|
319 |
-
$source = array(
|
320 |
-
'name' => $filename,
|
321 |
-
'type' => 'url',
|
322 |
-
'path' => $post['url'],
|
323 |
-
);
|
324 |
-
}
|
325 |
|
326 |
-
|
327 |
-
|
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 |
-
}
|
338 |
-
else {
|
339 |
-
$filename = tempnam(XmlImportConfig::getInstance()->getCacheDirectory(), 'xim');
|
340 |
-
|
341 |
-
// Let's make sure the file exists and is writable first.
|
342 |
-
if (is_writable($filename)) {
|
343 |
-
|
344 |
-
if (!$handle = fopen($filename, 'w')) {
|
345 |
-
$this->errors->add('form-validation', __('Cannot open file ' . $filename, 'pmxi_plugin'));
|
346 |
-
}
|
347 |
-
|
348 |
-
// Write $somecontent to our opened file.
|
349 |
-
if (fwrite($handle, $xml) === FALSE) {
|
350 |
-
$this->errors->add('form-validation', __('Cannot write to file ' . $filename, 'pmxi_plugin'));
|
351 |
-
}
|
352 |
-
|
353 |
-
fclose($handle);
|
354 |
-
|
355 |
-
} else {
|
356 |
-
$this->errors->add('form-validation', __('The file' . $filename . 'is not writable', 'pmxi_plugin'));
|
357 |
-
}
|
358 |
-
$filePath = $filename;
|
359 |
$source = array(
|
360 |
-
'name' => basename(
|
361 |
-
'type' => '
|
362 |
-
'path' => $post['
|
363 |
-
);
|
364 |
-
}
|
365 |
-
}else {
|
366 |
-
$filePath = $post['url'];
|
367 |
-
$source = array(
|
368 |
-
'name' => basename(parse_url($filePath, PHP_URL_PATH)),
|
369 |
-
'type' => 'url',
|
370 |
-
'path' => $filePath,
|
371 |
-
);
|
372 |
|
373 |
-
|
374 |
-
} elseif ('ftp' == $this->input->post('type')) {
|
375 |
-
if (empty($post['ftp']['url'])) {
|
376 |
-
$this->errors->add('form-validation', __('XML/CSV file must be specified', 'pmxi_plugin'));
|
377 |
-
} elseif ( ! preg_match('%^ftps?://%i', $post['ftp']['url'])) {
|
378 |
-
$this->errors->add('form-validation', __('Specified FTP resource has wrong format'), 'pmxi_plugin');
|
379 |
-
} elseif ( preg_match('%\W(csv)$%i', trim($post['ftp']['url']))) {
|
380 |
-
// path to remote file
|
381 |
-
$remote_file = $post['ftp']['url'];
|
382 |
-
$local_file = tempnam(XmlImportConfig::getInstance()->getCacheDirectory(), 'xim');
|
383 |
-
|
384 |
-
// open some file to write to
|
385 |
-
$handle = fopen($local_file, 'w');
|
386 |
-
|
387 |
-
// set up basic connection
|
388 |
-
$ftp_url = $post['ftp']['url'];
|
389 |
-
$parsed_url = parse_url($ftp_url);
|
390 |
-
$ftp_server = $parsed_url['host'] ;
|
391 |
-
$conn_id = ftp_connect( $ftp_server );
|
392 |
-
$is_ftp_ok = TRUE;
|
393 |
-
|
394 |
-
// login with username and password
|
395 |
-
$ftp_user_name = $post['ftp']['user'];
|
396 |
-
$ftp_user_pass = $post['ftp']['pass'];
|
397 |
-
|
398 |
-
// hide warning message
|
399 |
-
echo '<span style="display:none">';
|
400 |
-
if ( !ftp_login($conn_id, $ftp_user_name, $ftp_user_pass) ){
|
401 |
-
$this->errors->add('form-validation', __('Login authentication failed', 'pmxi_plugin'));
|
402 |
-
$is_ftp_ok = false;
|
403 |
-
}
|
404 |
-
echo '</span>';
|
405 |
-
|
406 |
|
407 |
-
if ( $is_ftp_ok ){
|
408 |
-
// try to download $remote_file and save it to $handle
|
409 |
-
if (!ftp_fget($conn_id, $handle, $parsed_url['path'], FTP_ASCII, 0)) {
|
410 |
-
$this->errors->add('form-validation', __('There was a problem while downloading' . $remote_file . 'to' . $local_file, 'pmxi_plugin'));
|
411 |
-
}
|
412 |
-
|
413 |
-
// close the connection and the file handler
|
414 |
-
ftp_close($conn_id);
|
415 |
-
fclose($handle);
|
416 |
-
|
417 |
-
// copy file in temporary folder
|
418 |
-
$uploads = wp_upload_dir();
|
419 |
if($uploads['error']){
|
420 |
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
421 |
-
}
|
422 |
-
|
423 |
-
|
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 |
}
|
433 |
-
else
|
434 |
-
|
435 |
-
$
|
436 |
-
|
437 |
-
|
438 |
-
if (is_writable($filename)) {
|
439 |
-
|
440 |
-
if (!$handle = fopen($filename, 'w')) {
|
441 |
-
$this->errors->add('form-validation', __('Cannot open file ' . $filename, 'pmxi_plugin'));
|
442 |
-
}
|
443 |
-
|
444 |
-
// Write $somecontent to our opened file.
|
445 |
-
if (fwrite($handle, $xml) === FALSE) {
|
446 |
-
$this->errors->add('form-validation', __('Cannot write to file ' . $filename, 'pmxi_plugin'));
|
447 |
-
}
|
448 |
-
|
449 |
-
fclose($handle);
|
450 |
-
|
451 |
-
} else {
|
452 |
-
$this->errors->add('form-validation', __('The file' . $filename . 'is not writable', 'pmxi_plugin'));
|
453 |
-
}
|
454 |
-
$filePath = $local_file;
|
455 |
-
$source = array(
|
456 |
-
'name' => basename($local_file),
|
457 |
-
'type' => 'ftp',
|
458 |
-
'path' => $filePath,
|
459 |
-
);
|
460 |
}
|
461 |
-
}
|
462 |
-
} else {
|
463 |
-
$filePath = $post['ftp']['url'];
|
464 |
-
if (isset($post['ftp']['user']) and $post['ftp']['user'] !== '') {
|
465 |
-
$filePath = preg_replace('%://([^@/]*@)?%', '://' . urlencode($post['ftp']['user']) . ':' . urlencode($post['ftp']['pass']) . '@', $filePath, 1);
|
466 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
467 |
$source = array(
|
468 |
-
'name' => basename(
|
469 |
-
'type' => '
|
470 |
'path' => $filePath,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
471 |
);
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
// hide warning message
|
484 |
-
echo '<span style="display:none">';
|
485 |
-
copy( $uploads . $post['file'], $wp_uploads['path'] . basename($post['file']));
|
486 |
-
echo '</span>';
|
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 |
-
}
|
497 |
-
else {
|
498 |
-
$filename = $wp_uploads['path'] . basename($post['file']);
|
499 |
-
|
500 |
-
// Let's make sure the file exists and is writable first.
|
501 |
-
if (is_writable($filename)) {
|
502 |
-
|
503 |
-
if (!$handle = fopen($filename, 'w')) {
|
504 |
-
$this->errors->add('form-validation', __('Cannot open file ' . $filename, 'pmxi_plugin'));
|
505 |
-
}
|
506 |
-
|
507 |
-
// Write $somecontent to our opened file.
|
508 |
-
if (fwrite($handle, $xml) === FALSE) {
|
509 |
-
$this->errors->add('form-validation', __('Cannot write to file ' . $filename, 'pmxi_plugin'));
|
510 |
-
}
|
511 |
-
|
512 |
-
fclose($handle);
|
513 |
-
|
514 |
-
} else {
|
515 |
-
$this->errors->add('form-validation', __('The file ' . $filename . ' is not writable or you use wildcard for CSV file', 'pmxi_plugin'));
|
516 |
}
|
517 |
-
$filePath = $wp_uploads['path'] . basename($post['file']);
|
518 |
-
$source = array(
|
519 |
-
'name' => basename(parse_url($filePath, PHP_URL_PATH)),
|
520 |
-
'type' => 'file',
|
521 |
-
'path' => $filePath,
|
522 |
-
);
|
523 |
-
}
|
524 |
}
|
525 |
-
|
526 |
-
|
|
|
|
|
|
|
|
|
527 |
$source = array(
|
528 |
-
'name' => basename(
|
529 |
-
'type' => '
|
530 |
'path' => $filePath,
|
531 |
);
|
532 |
-
}
|
533 |
-
}
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
}
|
538 |
-
|
539 |
if ($post['is_update_previous'] and empty($post['update_previous'])) {
|
540 |
-
$this->errors->add('form-validation', __('Previous import for update must be selected
|
541 |
}
|
542 |
|
543 |
if ($this->input->post('is_submitted') and ! $this->errors->get_error_codes()) {
|
544 |
|
545 |
-
check_admin_referer('choose-file', '_wpnonce_choose-file');
|
|
|
|
|
546 |
|
547 |
-
if (
|
548 |
-
preg_match('%^#(\d+):%', $post['reimport'], $mtch) and $reimport_id = $mtch[1] or $reimport_id = 0;
|
549 |
-
$file = new PMXI_File_Record();
|
550 |
-
if ( ! $reimport_id or $file->getById($reimport_id)->isEmpty()) {
|
551 |
-
$xml = FALSE;
|
552 |
-
} else {
|
553 |
-
$xml = @file_get_contents($file->path);
|
554 |
|
555 |
-
|
|
|
|
|
|
|
|
|
556 |
|
557 |
-
$
|
558 |
-
|
559 |
-
|
560 |
-
'path' => $file->path,
|
561 |
-
);
|
562 |
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
573 |
|
574 |
-
|
575 |
-
|
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)) {
|
589 |
// xml is valid
|
590 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
591 |
$_SESSION['pmxi_import'] = array(
|
592 |
'xml' => $xml,
|
593 |
-
'
|
594 |
-
|
595 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
596 |
$update_previous = new PMXI_Import_Record();
|
597 |
if ($post['is_update_previous'] and ! $update_previous->getById($post['update_previous'])->isEmpty()) {
|
598 |
$_SESSION['pmxi_import'] += array(
|
@@ -604,8 +406,9 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
604 |
} else {
|
605 |
$_SESSION['pmxi_import']['update_previous'] = '';
|
606 |
}
|
607 |
-
|
608 |
wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
|
|
|
609 |
}
|
610 |
}
|
611 |
|
@@ -617,11 +420,13 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
617 |
*/
|
618 |
public function element()
|
619 |
{
|
620 |
-
|
621 |
-
|
622 |
$xpath = new DOMXPath($this->data['dom']);
|
623 |
$post = $this->input->post(array('xpath' => ''));
|
624 |
$this->data['post'] =& $post;
|
|
|
|
|
|
|
625 |
|
626 |
if ($this->input->post('is_submitted')) {
|
627 |
check_admin_referer('choose-elements', '_wpnonce_choose-elements');
|
@@ -643,23 +448,72 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
643 |
}
|
644 |
}
|
645 |
}
|
|
|
646 |
if ( ! $this->errors->get_error_codes()) {
|
647 |
$_SESSION['pmxi_import']['xpath'] = $post['xpath'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
648 |
wp_redirect(add_query_arg('action', 'template', $this->baseUrl)); die();
|
649 |
}
|
650 |
} else {
|
651 |
|
652 |
-
|
653 |
|
654 |
if (isset($_SESSION['pmxi_import']['xpath'])) {
|
655 |
$post['xpath'] = $_SESSION['pmxi_import']['xpath'];
|
656 |
-
|
|
|
657 |
$_GET['pmxi_nt'] = __('<b>Warning</b>: No matching elements found for XPath expression from the import being updated. It probably means that new XML file has different format. Though you can update XPath, procceed only if you sure about update operation being valid.', 'pmxi_plugin');
|
658 |
}
|
659 |
} else {
|
660 |
// suggest 1st repeating element as default selection
|
661 |
$post['xpath'] = $this->xml_find_repeating($this->data['dom']->documentElement);
|
|
|
|
|
|
|
662 |
}
|
|
|
663 |
}
|
664 |
|
665 |
// workaround to prevent rendered XML representation to eat memory since it has to be stored in momory when output is bufferred
|
@@ -681,33 +535,85 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
681 |
}
|
682 |
|
683 |
$xpath = new DOMXPath($this->data['dom']);
|
684 |
-
$post = $this->input->post(array('xpath' => ''));
|
|
|
|
|
685 |
if ('' == $post['xpath']) {
|
686 |
$this->errors->add('form-validation', __('No elements selected', 'pmxi_plugin'));
|
687 |
-
} else {
|
688 |
-
|
689 |
-
$
|
690 |
-
|
691 |
-
$this->
|
692 |
-
|
693 |
-
$
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
700 |
}
|
701 |
}
|
702 |
}
|
703 |
if ( ! $this->errors->get_error_codes()) {
|
704 |
-
|
|
|
705 |
$xpath = new DOMXPath($this->data['dom']);
|
706 |
-
$this->data['
|
707 |
|
708 |
$paths = array(); $this->data['paths'] =& $paths;
|
709 |
-
if (PMXI_Plugin::getInstance()->getOption('highlight_limit') and $
|
710 |
-
foreach ($
|
711 |
if ( ! $el instanceof DOMElement) continue;
|
712 |
|
713 |
$p = $this->get_xml_path($el, $xpath) and $paths[] = $p;
|
@@ -731,25 +637,27 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
731 |
'content' => '',
|
732 |
'name' => '',
|
733 |
'is_keep_linebreaks' => 0,
|
734 |
-
|
|
|
735 |
if ($this->isWizard) {
|
736 |
$this->data['post'] = $post = $this->input->post(
|
737 |
(isset($_SESSION['pmxi_import']['template']) ? $_SESSION['pmxi_import']['template'] : array())
|
738 |
+ $default
|
739 |
);
|
740 |
-
} else {
|
741 |
$this->data['post'] = $post = $this->input->post(
|
742 |
$this->data['import']->template
|
743 |
+ $default
|
744 |
-
);
|
745 |
-
}
|
746 |
|
747 |
if (($load_template = $this->input->post('load_template'))) { // init form with template selected
|
748 |
if ( ! $template->getById($load_template)->isEmpty()) {
|
749 |
$this->data['post'] = array(
|
750 |
'title' => $template->title,
|
751 |
'content' => $template->content,
|
752 |
-
'is_keep_linebreaks' => $template->is_keep_linebreaks,
|
|
|
753 |
'name' => '', // template is always empty
|
754 |
);
|
755 |
$_SESSION['pmxi_import']['is_loaded_template'] = $load_template;
|
@@ -763,22 +671,22 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
763 |
} else {
|
764 |
$this->_validate_template($post['title'], 'Post title');
|
765 |
}
|
|
|
766 |
if (empty($post['content'])) {
|
767 |
$this->errors->add('form-validation', __('Post content is empty', 'pmxi_plugin'));
|
768 |
} else {
|
769 |
$this->_validate_template($post['content'], 'Post content');
|
770 |
-
}
|
771 |
-
|
772 |
|
773 |
-
if ( ! $this->errors->get_error_codes()) {
|
774 |
if ( ! empty($post['name'])) { // save template in database
|
775 |
$template->getByName($post['name'])->set($post)->save();
|
776 |
-
$_SESSION['pmxi_import']['saved_template'] = $template->id;
|
777 |
}
|
778 |
if ($this->isWizard) {
|
779 |
-
$_SESSION['pmxi_import']['template'] = $post;
|
780 |
wp_redirect(add_query_arg('action', 'options', $this->baseUrl)); die();
|
781 |
-
} else {
|
782 |
$this->data['import']->set('template', $post)->save();
|
783 |
wp_redirect(add_query_arg(array('page' => 'pmxi-admin-manage', 'pmlc_nt' => urlencode(__('Template updated', 'pmxi_plugin'))) + array_intersect_key($_GET, array_flip($this->baseUrlParamNames)), admin_url('admin.php'))); die();
|
784 |
}
|
@@ -795,6 +703,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
795 |
wp_enqueue_script('quicktags');
|
796 |
$this->render();
|
797 |
}
|
|
|
798 |
protected function _validate_template($text, $field_title)
|
799 |
{
|
800 |
try {
|
@@ -811,10 +720,12 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
811 |
* Preview selected xml tag (called with ajax from `template` step)
|
812 |
*/
|
813 |
public function tag()
|
814 |
-
{
|
815 |
-
if (empty($this->data['elements']))
|
816 |
-
{
|
817 |
|
|
|
|
|
|
|
|
|
818 |
$update_previous = new PMXI_Import_Record();
|
819 |
if ($update_previous->getById($this->input->get('id'))) {
|
820 |
$_SESSION['pmxi_import'] = array(
|
@@ -823,24 +734,65 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
823 |
'template' => $update_previous->template,
|
824 |
'options' => $update_previous->options,
|
825 |
);
|
826 |
-
$
|
827 |
-
$
|
828 |
-
$
|
829 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
830 |
} else {
|
831 |
$_SESSION['pmxi_import']['update_previous'] = '';
|
832 |
-
}
|
833 |
-
if (!empty($_SESSION['pmxi_import']['xml']))
|
834 |
-
{
|
835 |
-
$dom = new DOMDocument();
|
836 |
-
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $_SESSION['pmxi_import']['xml']));
|
837 |
-
$xpath = new DOMXPath($dom);
|
838 |
-
|
839 |
-
$this->data['elements'] = $elements = $xpath->query($_SESSION['pmxi_import']['xpath']);
|
840 |
-
}
|
841 |
}
|
842 |
|
843 |
-
$this->data['tagno'] = min(max(intval($this->input->getpost('tagno', 1)), 1), $this->data['elements']->length);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
844 |
$this->render();
|
845 |
}
|
846 |
|
@@ -853,12 +805,43 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
853 |
'title' => '',
|
854 |
'content' => '',
|
855 |
'is_keep_linebreaks' => 0,
|
856 |
-
|
857 |
-
|
858 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
859 |
// validate
|
860 |
try {
|
861 |
-
|
862 |
if (empty($post['title'])) {
|
863 |
$this->errors->add('form-validation', __('Post title is empty', 'pmxi_plugin'));
|
864 |
} else {
|
@@ -866,11 +849,12 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
866 |
if ( ! isset($this->data['title']) or '' == strval(trim(strip_tags($this->data['title'], '<img><input><textarea><iframe><object><embed>')))) {
|
867 |
$this->errors->add('xml-parsing', __('<strong>Warning</strong>: resulting post title is empty', 'pmxi_plugin'));
|
868 |
}
|
|
|
869 |
}
|
870 |
} catch (XmlImportException $e) {
|
871 |
$this->errors->add('form-validation', sprintf(__('Error parsing title: %s', 'pmxi_plugin'), $e->getMessage()));
|
872 |
}
|
873 |
-
try {
|
874 |
if (empty($post['content'])) {
|
875 |
$this->errors->add('form-validation', __('Post content is empty', 'pmxi_plugin'));
|
876 |
} else {
|
@@ -878,6 +862,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
878 |
if ( ! isset($this->data['content']) or '' == strval(trim(strip_tags($this->data['content'], '<img><input><textarea><iframe><object><embed>')))) {
|
879 |
$this->errors->add('xml-parsing', __('<strong>Warning</strong>: resulting post content is empty', 'pmxi_plugin'));
|
880 |
}
|
|
|
881 |
}
|
882 |
} catch (XmlImportException $e) {
|
883 |
$this->errors->add('form-validation', sprintf(__('Error parsing content: %s', 'pmxi_plugin'), $e->getMessage()));
|
@@ -898,16 +883,41 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
898 |
if ($this->isWizard) {
|
899 |
$this->data['source_type'] = $_SESSION['pmxi_import']['source']['type'];
|
900 |
$default['unique_key'] = $_SESSION['pmxi_import']['template']['title'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
901 |
$post = $this->input->post(
|
902 |
(isset($_SESSION['pmxi_import']['options']) ? $_SESSION['pmxi_import']['options'] : array())
|
903 |
+ $default
|
904 |
);
|
905 |
|
906 |
$scheduled = $this->input->post(array(
|
907 |
-
'is_scheduled' => ! empty($
|
908 |
-
'scheduled_period' => ! empty($
|
909 |
));
|
910 |
-
|
911 |
} else {
|
912 |
$this->data['source_type'] = $this->data['import']->type;
|
913 |
$post = $this->input->post(
|
@@ -919,15 +929,21 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
919 |
'scheduled_period' => ! empty($this->data['import']->scheduled) ? $this->data['import']->scheduled : '0 0 * * *', // daily by default
|
920 |
));
|
921 |
}
|
|
|
922 |
$this->data['post'] =& $post;
|
923 |
$this->data['scheduled'] =& $scheduled;
|
924 |
$this->data['is_loaded_template'] = $_SESSION['pmxi_import']['is_loaded_template'];
|
925 |
|
|
|
|
|
|
|
|
|
|
|
926 |
if (($load_options = $this->input->post('load_options'))) { // init form with template selected
|
927 |
$this->data['load_options'] = true;
|
928 |
$template = new PMXI_Template_Record();
|
929 |
-
if ( ! $template->getById($this->data['is_loaded_template'])->isEmpty()) {
|
930 |
-
$post = $template->options + $default;
|
931 |
$scheduled = array(
|
932 |
'is_scheduled' => ! empty($template->scheduled),
|
933 |
'scheduled_period' => ! empty($template->scheduled) ? $template->scheduled : '0 0 * * *', // daily by default
|
@@ -938,25 +954,11 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
938 |
$post = $default;
|
939 |
$scheduled = $this->input->post(array(
|
940 |
'is_scheduled' => ! empty($post['scheduled']),
|
941 |
-
'scheduled_period' => ! empty($post['scheduled']) ? $post['
|
942 |
));
|
943 |
} elseif ($this->input->post('is_submitted')) {
|
944 |
-
check_admin_referer('options', '_wpnonce_options');
|
945 |
-
|
946 |
-
$not_empty = array_flip(array_values(array_merge(array_keys(array_filter($post['custom_name'])), array_keys(array_filter($post['custom_value'])))));
|
947 |
-
$post['custom_name'] = array_intersect_key($post['custom_name'], $not_empty);
|
948 |
-
$post['custom_value'] = array_intersect_key($post['custom_value'], $not_empty);
|
949 |
-
// validate
|
950 |
-
if (array_keys(array_filter($post['custom_name'])) != array_keys(array_filter($post['custom_value']))) {
|
951 |
-
$this->errors->add('form-validation', __('Both name and value must be set for all custom parameters', 'pmxi_plugin'));
|
952 |
-
} else {
|
953 |
-
foreach ($post['custom_name'] as $custom_name) {
|
954 |
-
$this->_validate_template($custom_name, __('Custom Field Name', 'pmxi_plugin'));
|
955 |
-
}
|
956 |
-
foreach ($post['custom_value'] as $custom_value) {
|
957 |
-
$this->_validate_template($custom_value, __('Custom Field Value', 'pmxi_plugin'));
|
958 |
-
}
|
959 |
-
}
|
960 |
if ('page' == $post['type'] and ! preg_match('%^(-?\d+)?$%', $post['order'])) {
|
961 |
$this->errors->add('form-validation', __('Order must be an integer number', 'pmxi_plugin'));
|
962 |
}
|
@@ -982,7 +984,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
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 |
}
|
@@ -994,6 +996,12 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
994 |
} else {
|
995 |
$this->_validate_template($post['unique_key'], __('Post Unique Key', 'pmxi_plugin'));
|
996 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
997 |
|
998 |
if ( ! $this->errors->get_error_codes()) { // no validation errors found
|
999 |
// assign some defaults
|
@@ -1032,6 +1040,8 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
1032 |
'template' => $_SESSION['pmxi_import']['template'],
|
1033 |
'options' => $_SESSION['pmxi_import']['options'],
|
1034 |
'scheduled' => $_SESSION['pmxi_import']['scheduled'],
|
|
|
|
|
1035 |
)
|
1036 |
)->save();
|
1037 |
|
@@ -1039,7 +1049,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
1039 |
$history_file->set(array(
|
1040 |
'name' => $import->name,
|
1041 |
'import_id' => $import->id,
|
1042 |
-
'path' => $
|
1043 |
'contents' => $_SESSION['pmxi_import']['xml'],
|
1044 |
'registered_on' => date('Y-m-d H:i:s'),
|
1045 |
))->save();
|
@@ -1047,7 +1057,8 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
1047 |
wp_redirect(add_query_arg(array('page' => 'pmxi-admin-manage', 'pmlc_nt' => urlencode($is_update ? __('Import updated', 'pmxi_plugin') : __('Import created', 'pmxi_plugin'))), admin_url('admin.php'))); die();
|
1048 |
}
|
1049 |
} else {
|
1050 |
-
|
|
|
1051 |
$template = new PMXI_Template_Record();
|
1052 |
|
1053 |
if (!$template->getByName($this->data['import']->template['name'])->isEmpty()){
|
@@ -1058,9 +1069,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
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 |
}
|
1061 |
-
}
|
1062 |
-
|
1063 |
-
! empty($post['custom_name']) or $post['custom_name'] = array('') and $post['custom_value'] = array('');
|
1064 |
|
1065 |
$this->render();
|
1066 |
}
|
@@ -1068,107 +1077,232 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
1068 |
/**
|
1069 |
* Import processing step (status console)
|
1070 |
*/
|
1071 |
-
public function process()
|
1072 |
{
|
1073 |
-
$
|
1074 |
-
wp_ob_end_flush_all(); flush();
|
1075 |
-
|
1076 |
-
set_time_limit(0);
|
1077 |
|
1078 |
-
|
1079 |
-
|
|
|
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 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1089 |
|
1090 |
-
$logger
|
|
|
|
|
1091 |
|
1092 |
-
if (
|
1093 |
-
$import->
|
1094 |
-
} else { // directly process XML
|
1095 |
-
$import->process($_SESSION['pmxi_import']['xml'], $logger);
|
1096 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1097 |
|
1098 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1099 |
|
1100 |
// [indicate in header process is complete]
|
1101 |
-
$msg = addcslashes(__('Complete', 'pmxi_plugin'), "'\n\r");
|
|
|
|
|
|
|
|
|
1102 |
echo <<<COMPLETE
|
1103 |
<script type="text/javascript">
|
1104 |
//<![CDATA[
|
1105 |
(function($){
|
|
|
|
|
|
|
|
|
|
|
|
|
1106 |
$('#status').html('$msg');
|
1107 |
window.onbeforeunload = false;
|
1108 |
})(jQuery);
|
1109 |
//]]>
|
1110 |
</script>
|
1111 |
COMPLETE;
|
1112 |
-
|
1113 |
-
}
|
1114 |
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
function removeNode($xml, $path)
|
1119 |
-
{
|
1120 |
-
$result = $xml->xpath($path);
|
1121 |
-
|
1122 |
-
if (empty($result)) return false;
|
1123 |
-
$errlevel = error_reporting(E_ALL & ~E_WARNING);
|
1124 |
-
foreach ($result as $r) unset ($r[0]);
|
1125 |
-
error_reporting($errlevel);
|
1126 |
-
|
1127 |
-
return true;
|
1128 |
-
}
|
1129 |
-
|
1130 |
-
/*
|
1131 |
-
*
|
1132 |
-
* Get SimpleXML object by xpath extension
|
1133 |
-
*
|
1134 |
-
*/
|
1135 |
-
function get_chank(& $xml, $path){
|
1136 |
-
|
1137 |
-
$result = $xml->xpath($path);
|
1138 |
-
|
1139 |
-
$array = array();
|
1140 |
-
foreach ($result as $el) {
|
1141 |
-
array_push($array, $this->simplexml2array($el));
|
1142 |
-
}
|
1143 |
-
|
1144 |
-
if (empty($array)) return false;
|
1145 |
-
|
1146 |
-
return new SimpleXMLElement(ArrayToXML::toXml($array));
|
1147 |
-
}
|
1148 |
-
|
1149 |
-
/*
|
1150 |
-
*
|
1151 |
-
* Convert SimpleXML object to array
|
1152 |
-
*
|
1153 |
-
*/
|
1154 |
-
function simplexml2array($xml) {
|
1155 |
-
if (@get_class($xml) == 'SimpleXMLElement') {
|
1156 |
-
$attributes = $xml->attributes();
|
1157 |
-
foreach($attributes as $k=>$v) {
|
1158 |
-
if ($v) $a[$k] = (string) $v;
|
1159 |
-
}
|
1160 |
-
$x = $xml;
|
1161 |
-
$xml = get_object_vars($xml);
|
1162 |
-
}
|
1163 |
-
if (is_array($xml)) {
|
1164 |
-
if (count($xml) == 0) return (string) $x; // for CDATA
|
1165 |
-
foreach($xml as $key=>$value) {
|
1166 |
-
$r[$key] = $this->simplexml2array($value);
|
1167 |
-
}
|
1168 |
-
if (isset($a)) $r['@attributes'] = $a; // Attributes
|
1169 |
-
return $r;
|
1170 |
-
}
|
1171 |
-
return (string) $xml;
|
1172 |
}
|
1173 |
|
1174 |
protected $_sibling_limit = 20;
|
@@ -1227,10 +1361,10 @@ COMPLETE;
|
|
1227 |
}
|
1228 |
protected function render_xml_element(DOMElement $el, $shorten = false, $path = '/', $ind = 1, $lvl = 0)
|
1229 |
{
|
1230 |
-
$path .= $el->nodeName;
|
1231 |
if ( ! $el->parentNode instanceof DOMDocument and $ind > 0) {
|
1232 |
$path .= "[$ind]";
|
1233 |
-
}
|
1234 |
|
1235 |
echo '<div class="xml-element lvl-' . $lvl . ' lvl-mod4-' . ($lvl % 4) . '" title="' . $path . '">';
|
1236 |
if ($el->hasChildNodes()) {
|
@@ -1265,6 +1399,19 @@ COMPLETE;
|
|
1265 |
}
|
1266 |
echo '</div>';
|
1267 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1268 |
protected function render_xml_text($text, $shorten = false, $is_render_collapsed = false)
|
1269 |
{
|
1270 |
if (empty($text)) {
|
@@ -1396,5 +1543,11 @@ COMPLETE;
|
|
1396 |
|
1397 |
return NULL;
|
1398 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1399 |
|
1400 |
}
|
12 |
protected function init() {
|
13 |
parent::init();
|
14 |
|
15 |
+
try{
|
16 |
+
$path = session_save_path();
|
17 |
+
if ( ! is_dir($path) or ! is_writable($path)){
|
18 |
+
@ini_set("session.save_handler", "files");
|
19 |
+
session_save_path(sys_get_temp_dir());
|
20 |
+
}
|
21 |
+
} catch (XmlImportException $e) {
|
22 |
+
$this->errors->add('form-validation', __('Can not create session.', 'pmxi_plugin'));
|
23 |
+
}
|
24 |
+
|
25 |
// enable sessions
|
26 |
if ( ! session_id()) session_start();
|
27 |
|
28 |
if ('PMXI_Admin_Manage' == PMXI_Plugin::getInstance()->getAdminCurrentScreen()->base) { // prereqisites are not checked when flow control is deligated
|
29 |
$id = $this->input->get('id');
|
30 |
+
$this->data['import'] = $import = new PMXI_Import_Record();
|
31 |
if ( ! $id or $import->getById($id)->isEmpty()) { // specified import is not found
|
32 |
wp_redirect(add_query_arg('page', 'pmxi-admin-manage', admin_url('admin.php'))); die();
|
33 |
}
|
34 |
$this->isWizard = false;
|
35 |
|
36 |
} else {
|
37 |
+
$action = PMXI_Plugin::getInstance()->getAdminCurrentScreen()->action;
|
38 |
$this->_step_ready($action);
|
39 |
$this->isInline = 'process' == $action;
|
40 |
+
}
|
41 |
|
42 |
XmlImportConfig::getInstance()->setCacheDirectory(sys_get_temp_dir());
|
43 |
|
52 |
public function get($var)
|
53 |
{
|
54 |
return $this->{$var};
|
55 |
+
}
|
56 |
|
57 |
/**
|
58 |
* Checks whether corresponding step of wizard is complete
|
59 |
* @param string $action
|
60 |
*/
|
61 |
+
protected function _step_ready($action) {
|
62 |
// step #1: xml selction - has no prerequisites
|
63 |
if ('index' == $action) return true;
|
64 |
|
65 |
// step #2: element selection
|
66 |
+
$this->data['dom'] = $dom = new DOMDocument('1.0', 'UTF-8');
|
67 |
$this->data['update_previous'] = $update_previous = new PMXI_Import_Record();
|
68 |
$old = libxml_use_internal_errors(true);
|
69 |
+
|
70 |
if (empty($_SESSION['pmxi_import'])
|
71 |
+
or ! $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $_SESSION['pmxi_import']['xml']))// FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
72 |
+
//or empty($_SESSION['pmxi_import']['source'])
|
73 |
or ! empty($_SESSION['pmxi_import']['update_previous']) and $update_previous->getById($_SESSION['pmxi_import']['update_previous'])->isEmpty()
|
74 |
) {
|
75 |
+
$this->errors->add('form-validation', __('Can not create DOM object for provided feed.', 'pmxi_plugin'));
|
76 |
wp_redirect_or_javascript($this->baseUrl); die();
|
77 |
}
|
78 |
libxml_use_internal_errors($old);
|
79 |
if ('element' == $action) return true;
|
80 |
if ('evaluate' == $action) return true;
|
81 |
+
|
82 |
// step #3: template
|
83 |
$xpath = new DOMXPath($dom);
|
84 |
+
|
85 |
if (empty($_SESSION['pmxi_import']['xpath']) or ! ($this->data['elements'] = $elements = $xpath->query($_SESSION['pmxi_import']['xpath'])) or ! $elements->length) {
|
86 |
+
$this->errors->add('form-validation', __('No matching elements found.', 'pmxi_plugin'));
|
87 |
wp_redirect_or_javascript(add_query_arg('action', 'element', $this->baseUrl)); die();
|
88 |
}
|
89 |
if ('template' == $action or 'preview' == $action or 'tag' == $action) return true;
|
104 |
*/
|
105 |
public function index() {
|
106 |
|
107 |
+
$this->data['reimported_import'] = $import = new PMXI_Import_Record();
|
108 |
$this->data['id'] = $id = $this->input->get('id');
|
109 |
if ($id and $import->getById($id)->isEmpty()) { // update requested but corresponding import is not found
|
110 |
wp_redirect(remove_query_arg('id', $this->baseUrl)); die();
|
118 |
'reimport' => '',
|
119 |
'is_update_previous' => $id ? 1 : 0,
|
120 |
'update_previous' => $id,
|
121 |
+
'xpath' => '/',
|
122 |
+
'large_file' => '',
|
123 |
+
'filepath' => '',
|
124 |
+
'root_element' => ''
|
125 |
));
|
126 |
+
|
|
|
|
|
|
|
127 |
$this->data['history'] = $history = new PMXI_File_List();
|
128 |
$history->setColumns('id', 'name', 'registered_on', 'path')->getBy(NULL, 'id DESC');
|
129 |
|
130 |
+
if ($history->count())
|
131 |
+
{
|
132 |
+
$uploads = wp_upload_dir();
|
133 |
+
foreach ($history as $file){
|
134 |
+
if (file_exists(PMXI_Plugin::ROOT_DIR . '/history/' . $file['id']) and !file_exists($uploads['basedir'] . '/wpallimport_history/' . $file['id']))
|
135 |
+
{
|
136 |
+
$fdata = @file_get_contents(PMXI_Plugin::ROOT_DIR . '/history/' . $file['id']);
|
137 |
+
@file_put_contents($uploads['basedir'] . '/wpallimport_history/' . $file['id'], $fdata);
|
138 |
+
}
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
if ($this->input->post('is_submitted_continue')) {
|
143 |
if ( ! empty($_SESSION['pmxi_import']['xml'])) {
|
144 |
wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
|
145 |
}
|
146 |
+
} elseif ('upload' == $this->input->post('type')) {
|
147 |
+
|
148 |
+
$uploads = wp_upload_dir();
|
149 |
+
|
150 |
+
if (empty($post['filepath'])) {
|
151 |
$this->errors->add('form-validation', __('XML/CSV file must be specified', 'pmxi_plugin'));
|
152 |
+
} elseif (!is_file($post['filepath'])) {
|
153 |
$this->errors->add('form-validation', __('Uploaded file is empty', 'pmxi_plugin'));
|
154 |
+
} elseif ( ! preg_match('%\W(xml|gzip|zip|csv|gz)$%i', trim(basename($post['filepath'])))) {
|
155 |
$this->errors->add('form-validation', __('Uploaded file must be XML, CSV or ZIP, GZIP', 'pmxi_plugin'));
|
156 |
+
} elseif (preg_match('%\W(zip)$%i', trim(basename($post['filepath'])))) {
|
157 |
+
|
158 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/pclzip.lib.php');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
159 |
|
160 |
+
$archive = new PclZip($post['filepath']);
|
161 |
+
if (($v_result_list = $archive->extract(PCLZIP_OPT_PATH, $uploads['path'], PCLZIP_OPT_REPLACE_NEWER)) == 0) {
|
162 |
+
$this->errors->add('form-validation', 'Failed to open uploaded ZIP archive : '.$archive->errorInfo(true));
|
163 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
else {
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
|
166 |
+
$filePath = '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
|
168 |
+
if (!empty($v_result_list)){
|
169 |
+
foreach ($v_result_list as $unzipped_file) {
|
170 |
+
if ($unzipped_file['status'] == 'ok') $filePath = $unzipped_file['filename'];
|
171 |
+
}
|
172 |
+
}
|
173 |
if($uploads['error']){
|
174 |
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
175 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
|
177 |
+
if(empty($filePath)){
|
178 |
+
$zip = zip_open(trim($post['filepath']));
|
179 |
+
if (is_resource($zip)) {
|
180 |
+
while ($zip_entry = zip_read($zip)) {
|
181 |
+
$filePath = zip_entry_name($zip_entry);
|
182 |
+
$fp = fopen($uploads['path']."/".$filePath, "w");
|
183 |
+
if (zip_entry_open($zip, $zip_entry, "r")) {
|
184 |
+
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
|
185 |
+
fwrite($fp,"$buf");
|
186 |
+
zip_entry_close($zip_entry);
|
187 |
+
fclose($fp);
|
188 |
+
}
|
189 |
+
break;
|
190 |
+
}
|
191 |
+
zip_close($zip);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
|
193 |
+
} else {
|
194 |
+
$this->errors->add('form-validation', __('Failed to open uploaded ZIP archive. Can\'t extract files.', 'pmxi_plugin'));
|
195 |
+
}
|
196 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
|
198 |
+
// Detect if file is very large
|
199 |
+
$post['large_file'] = (filesize($filePath) > PMXI_Plugin::LARGE_SIZE) ? 'on' : false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
$source = array(
|
201 |
+
'name' => basename($post['filepath']),
|
202 |
+
'type' => 'upload',
|
203 |
+
'path' => $post['filepath'],
|
204 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
|
206 |
+
if (preg_match('%\W(csv)$%i', trim($filePath))){ // If CSV file found in archieve
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
208 |
if($uploads['error']){
|
209 |
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
210 |
+
}
|
211 |
+
if (empty($post['large_file'])) {
|
212 |
+
$filePath = PMXI_Plugin::csv_to_xml($filePath);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
}
|
214 |
+
else{
|
215 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
216 |
+
$csv = new PMXI_CsvParser($filePath, true); // create chunks
|
217 |
+
$filePath = $csv->xml_path;
|
218 |
+
$post['root_element'] = 'node';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
}
|
220 |
+
}
|
|
|
|
|
|
|
|
|
221 |
}
|
222 |
+
|
223 |
+
} elseif ( preg_match('%\W(csv)$%i', trim($post['filepath']))) { // If CSV file uploaded
|
224 |
+
|
225 |
+
// Detect if file is very large
|
226 |
+
$post['large_file'] = (filesize($post['filepath']) > PMXI_Plugin::LARGE_SIZE) ? 'on' : false;
|
227 |
+
|
228 |
+
if($uploads['error']){
|
229 |
+
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
230 |
+
}
|
231 |
+
$filePath = $post['filepath'];
|
232 |
$source = array(
|
233 |
+
'name' => basename($post['filepath']),
|
234 |
+
'type' => 'upload',
|
235 |
'path' => $filePath,
|
236 |
+
);
|
237 |
+
if (empty($post['large_file'])) {
|
238 |
+
$filePath = PMXI_Plugin::csv_to_xml($post['filepath']);
|
239 |
+
} else{
|
240 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
241 |
+
$csv = new PMXI_CsvParser($post['filepath'], true);
|
242 |
+
$filePath = $csv->xml_path;
|
243 |
+
$post['root_element'] = 'node';
|
244 |
+
}
|
245 |
+
} elseif(preg_match('%\W(gz)$%i', trim($post['filepath']))){ // If gz file uploaded
|
246 |
+
$fileInfo = pmxi_gzfile_get_contents($post['filepath']);
|
247 |
+
$filePath = $fileInfo['localPath'];
|
248 |
+
|
249 |
+
// Detect if file is very large
|
250 |
+
$post['large_file'] = (filesize($filePath) > PMXI_Plugin::LARGE_SIZE) ? 'on' : false;
|
251 |
+
|
252 |
+
$source = array(
|
253 |
+
'name' => basename($post['filepath']),
|
254 |
+
'type' => 'upload',
|
255 |
+
'path' => $post['filepath'],
|
256 |
);
|
257 |
+
|
258 |
+
// detect CSV or XML
|
259 |
+
if ( $fileInfo['type'] == 'csv') { // it is CSV file
|
260 |
+
if (empty($post['large_file'])) {
|
261 |
+
$filePath = PMXI_Plugin::csv_to_xml($filePath); // convert CSV to XML
|
262 |
+
}
|
263 |
+
else{
|
264 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
265 |
+
$csv = new PMXI_CsvParser($filePath, true); // create chunks
|
266 |
+
$filePath = $csv->xml_path;
|
267 |
+
$post['root_element'] = 'node';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
268 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
269 |
}
|
270 |
+
} else { // If XML file uploaded
|
271 |
+
|
272 |
+
// Detect if file is very large
|
273 |
+
$post['large_file'] = (filesize($post['filepath']) > PMXI_Plugin::LARGE_SIZE) ? 'on' : false;
|
274 |
+
|
275 |
+
$filePath = $post['filepath'];
|
276 |
$source = array(
|
277 |
+
'name' => basename($post['filepath']),
|
278 |
+
'type' => 'upload',
|
279 |
'path' => $filePath,
|
280 |
);
|
281 |
+
}
|
282 |
+
}
|
283 |
+
elseif ($this->input->post('is_submitted')){
|
284 |
+
|
285 |
+
$this->errors->add('form-validation', __('Upgrade to the paid edition of WP All Import to use this feature.', 'pmxi_plugin'));
|
286 |
}
|
287 |
+
|
288 |
if ($post['is_update_previous'] and empty($post['update_previous'])) {
|
289 |
+
$this->errors->add('form-validation', __('Previous import for update must be selected to proceed with a new one', 'pmxi_plugin'));
|
290 |
}
|
291 |
|
292 |
if ($this->input->post('is_submitted') and ! $this->errors->get_error_codes()) {
|
293 |
|
294 |
+
check_admin_referer('choose-file', '_wpnonce_choose-file');
|
295 |
+
|
296 |
+
$elements_cloud = array();
|
297 |
|
298 |
+
if (empty($xml)){
|
|
|
|
|
|
|
|
|
|
|
|
|
299 |
|
300 |
+
$wp_uploads = wp_upload_dir();
|
301 |
+
|
302 |
+
if (!empty($post['large_file'])){
|
303 |
+
|
304 |
+
set_time_limit(0);
|
305 |
|
306 |
+
$chunks = 0;
|
307 |
+
|
308 |
+
$chunk_path = '';
|
|
|
|
|
309 |
|
310 |
+
$local_paths = !empty($local_paths) ? $local_paths : array($filePath);
|
311 |
+
|
312 |
+
foreach ($local_paths as $key => $path) {
|
313 |
+
|
314 |
+
$file = new PMXI_Chunk($path, array('element' => $post['root_element'], 'path' => $wp_uploads['path']));
|
315 |
+
|
316 |
+
while ($chunk_xml = $file->read()) {
|
317 |
+
|
318 |
+
if (!empty($chunk_xml))
|
319 |
+
{
|
320 |
+
PMXI_Import_Record::preprocessXml($chunk_xml);
|
321 |
+
if ( ! $chunks ){ // save first chunk to the file
|
322 |
+
$chunk_path = $wp_uploads['path'] .'/'. wp_unique_filename($wp_uploads['path'], "chunk_".basename($path));
|
323 |
+
if (file_exists($chunk_path)) unlink($chunk_path);
|
324 |
+
file_put_contents($chunk_path, '<?xml version="1.0" encoding="utf-8"?>'."\n".$chunk_xml);
|
325 |
+
chmod($chunk_path, 0755);
|
326 |
+
}
|
327 |
+
$chunks++;
|
328 |
+
}
|
329 |
+
}
|
330 |
+
if ( ! $key ){
|
331 |
|
332 |
+
if ( ! empty($file->options['element'])) {
|
333 |
+
|
334 |
+
$post['root_element'] = $file->options['element'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
335 |
|
336 |
+
$xpath = "/".$post['root_element'];
|
337 |
+
|
338 |
+
$elements_cloud = $file->cloud;
|
339 |
+
|
340 |
+
if (empty($chunks)) { $this->errors->add('form-validation', __('No matching elements found for Root element and XPath expression specified', 'pmxi_plugin')); }
|
341 |
+
|
342 |
+
$filePath && $xml = @file_get_contents($chunk_path);
|
343 |
+
}
|
344 |
+
else $this->errors->add('form-validation', __('Unable to find root element for this feed. Please open the feed in your browser or a text editor and ensure it is a valid feed.', 'pmxi_plugin'));
|
345 |
+
}
|
346 |
+
}
|
347 |
+
|
348 |
+
} else {
|
349 |
+
|
350 |
+
ob_start();
|
351 |
+
$filePath && @readgzfile($filePath);
|
352 |
+
$xml = ob_get_clean();
|
353 |
+
|
354 |
+
if (empty($xml)){
|
355 |
+
$xml = @file_get_contents($filePath);
|
356 |
+
if (empty($xml)) get_file_curl($filePath, $wp_uploads['path'] .'/'. basename($filePath));
|
357 |
+
if (empty($xml)) $xml = @file_get_contents($wp_uploads['path'] .'/'. basename($filePath));
|
358 |
+
}
|
359 |
+
}
|
360 |
+
}
|
361 |
|
362 |
+
if ((empty($post['large_file']) and PMXI_Import_Record::validateXml($xml, $this->errors)) or (!empty($post['large_file']) and !empty($chunks))) {
|
363 |
// xml is valid
|
364 |
+
if (!empty($post['large_file'])){
|
365 |
+
$source['large_import'] = 'Yes';
|
366 |
+
$source['root_element'] = $post['root_element'];
|
367 |
+
}
|
368 |
+
else {
|
369 |
+
$source['large_import'] = 'No';
|
370 |
+
$source['root_element'] = '';
|
371 |
+
}
|
372 |
+
|
373 |
+
$source['first_import'] = date("Y-m-d H:i:s");
|
374 |
+
|
375 |
$_SESSION['pmxi_import'] = array(
|
376 |
'xml' => $xml,
|
377 |
+
'filePath' => $filePath,
|
378 |
+
'source' => $source,
|
379 |
+
'large_file' => (!empty($post['large_file'])) ? true : false,
|
380 |
+
'chunk_number' => 1,
|
381 |
+
'log' => '',
|
382 |
+
'current_post_ids' => '',
|
383 |
+
'processing' => 0,
|
384 |
+
'queue_chunk_number' => 0,
|
385 |
+
'count' => (isset($chunks)) ? $chunks : 0,
|
386 |
+
'created_records' => 0,
|
387 |
+
'updated_records' => 0,
|
388 |
+
'skipped_records' => 0,
|
389 |
+
'warnings' => 0,
|
390 |
+
'errors' => 0,
|
391 |
+
'start_time' => 0,
|
392 |
+
'local_paths' => (!empty($local_paths)) ? $local_paths : array(), // ftp import local copies of remote files
|
393 |
+
'action' => 'import',
|
394 |
+
'elements_cloud' => (!empty($elements_cloud)) ? $elements_cloud : array()
|
395 |
+
);
|
396 |
+
|
397 |
+
unset($xml);
|
398 |
$update_previous = new PMXI_Import_Record();
|
399 |
if ($post['is_update_previous'] and ! $update_previous->getById($post['update_previous'])->isEmpty()) {
|
400 |
$_SESSION['pmxi_import'] += array(
|
406 |
} else {
|
407 |
$_SESSION['pmxi_import']['update_previous'] = '';
|
408 |
}
|
409 |
+
|
410 |
wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
|
411 |
+
|
412 |
}
|
413 |
}
|
414 |
|
420 |
*/
|
421 |
public function element()
|
422 |
{
|
423 |
+
|
|
|
424 |
$xpath = new DOMXPath($this->data['dom']);
|
425 |
$post = $this->input->post(array('xpath' => ''));
|
426 |
$this->data['post'] =& $post;
|
427 |
+
$this->data['elements_cloud'] = $_SESSION['pmxi_import']['elements_cloud'];
|
428 |
+
|
429 |
+
$wp_uploads = wp_upload_dir();
|
430 |
|
431 |
if ($this->input->post('is_submitted')) {
|
432 |
check_admin_referer('choose-elements', '_wpnonce_choose-elements');
|
448 |
}
|
449 |
}
|
450 |
}
|
451 |
+
|
452 |
if ( ! $this->errors->get_error_codes()) {
|
453 |
$_SESSION['pmxi_import']['xpath'] = $post['xpath'];
|
454 |
+
// counting element selected by xPath
|
455 |
+
if ($_SESSION['pmxi_import']['large_file']){
|
456 |
+
|
457 |
+
$_SESSION['pmxi_import']['count'] = 0;
|
458 |
+
|
459 |
+
$this->data['node_list_count'] = 0;
|
460 |
+
|
461 |
+
// loop through the file until all lines are read
|
462 |
+
$first_loop = true;
|
463 |
+
|
464 |
+
foreach ($_SESSION['pmxi_import']['local_paths'] as $key => $path) {
|
465 |
+
|
466 |
+
$file = new PMXI_Chunk($path, array('element' => $_SESSION['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path'], 'type' => $this->input->post('type')));
|
467 |
+
|
468 |
+
while ($xml = $file->read()) {
|
469 |
+
|
470 |
+
if (!empty($xml))
|
471 |
+
{
|
472 |
+
PMXI_Import_Record::preprocessXml($xml);
|
473 |
+
|
474 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
475 |
+
$old = libxml_use_internal_errors(true);
|
476 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
477 |
+
libxml_use_internal_errors($old);
|
478 |
+
$xpath = new DOMXPath($dom);
|
479 |
+
if (($this->data['elements'] = $elements = @$xpath->query($post['xpath'])) and $elements->length){
|
480 |
+
$_SESSION['pmxi_import']['count']++;
|
481 |
+
$this->data['node_list_count']++;
|
482 |
+
if ($first_loop){
|
483 |
+
$_SESSION['pmxi_import']['xml'] = $xml;
|
484 |
+
$first_loop = false;
|
485 |
+
}
|
486 |
+
}
|
487 |
+
unset($dom, $xpath, $elements);
|
488 |
+
|
489 |
+
}
|
490 |
+
}
|
491 |
+
}
|
492 |
+
|
493 |
+
if ( ! $this->data['node_list_count']) {
|
494 |
+
$this->errors->add('form-validation', __('No matching elements found for XPath expression specified', 'pmxi_plugin'));
|
495 |
+
}
|
496 |
+
}
|
497 |
wp_redirect(add_query_arg('action', 'template', $this->baseUrl)); die();
|
498 |
}
|
499 |
} else {
|
500 |
|
501 |
+
//$this->shrink_xml_element($this->data['dom']->documentElement);
|
502 |
|
503 |
if (isset($_SESSION['pmxi_import']['xpath'])) {
|
504 |
$post['xpath'] = $_SESSION['pmxi_import']['xpath'];
|
505 |
+
$this->data['elements'] = $elements = $xpath->query($post['xpath']);
|
506 |
+
if ( ! $elements->length and ! empty($_SESSION['pmxi_import']['update_previous'])) {
|
507 |
$_GET['pmxi_nt'] = __('<b>Warning</b>: No matching elements found for XPath expression from the import being updated. It probably means that new XML file has different format. Though you can update XPath, procceed only if you sure about update operation being valid.', 'pmxi_plugin');
|
508 |
}
|
509 |
} else {
|
510 |
// suggest 1st repeating element as default selection
|
511 |
$post['xpath'] = $this->xml_find_repeating($this->data['dom']->documentElement);
|
512 |
+
if (!empty($post['xpath'])){
|
513 |
+
$this->data['elements'] = $elements = $xpath->query($post['xpath']);
|
514 |
+
}
|
515 |
}
|
516 |
+
|
517 |
}
|
518 |
|
519 |
// workaround to prevent rendered XML representation to eat memory since it has to be stored in momory when output is bufferred
|
535 |
}
|
536 |
|
537 |
$xpath = new DOMXPath($this->data['dom']);
|
538 |
+
$post = $this->input->post(array('xpath' => '', 'show_element' => 1, 'root_element' => $_SESSION['pmxi_import']['source']['root_element']));
|
539 |
+
$wp_uploads = wp_upload_dir();
|
540 |
+
|
541 |
if ('' == $post['xpath']) {
|
542 |
$this->errors->add('form-validation', __('No elements selected', 'pmxi_plugin'));
|
543 |
+
} else {
|
544 |
+
// counting selected elements
|
545 |
+
if ($_SESSION['pmxi_import']['large_file']){ // in large mode
|
546 |
+
|
547 |
+
$this->data['node_list_count'] = 0;
|
548 |
+
|
549 |
+
$_SESSION['pmxi_import']['count'] = 0;
|
550 |
+
|
551 |
+
$xpath_elements = explode('[', $post['xpath']);
|
552 |
+
$xpath_parts = explode('/', $xpath_elements[0]);
|
553 |
+
|
554 |
+
$_SESSION['pmxi_import']['source']['root_element'] = $xpath_parts[count($xpath_parts) - 1];
|
555 |
+
|
556 |
+
$loop = 1;
|
557 |
+
|
558 |
+
foreach ($_SESSION['pmxi_import']['local_paths'] as $key => $path) {
|
559 |
+
|
560 |
+
$file = new PMXI_Chunk($path, array('element' => $_SESSION['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path']));
|
561 |
+
// loop through the file until all lines are read
|
562 |
+
while ($xml = $file->read()) {
|
563 |
+
|
564 |
+
if (!empty($xml))
|
565 |
+
{
|
566 |
+
PMXI_Import_Record::preprocessXml($xml);
|
567 |
+
|
568 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
569 |
+
$old = libxml_use_internal_errors(true);
|
570 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
571 |
+
libxml_use_internal_errors($old);
|
572 |
+
$xpath = new DOMXPath($dom);
|
573 |
+
if (($this->data['elements'] = $elements = @$xpath->query($post['xpath'])) and $elements->length){
|
574 |
+
$_SESSION['pmxi_import']['count']++;
|
575 |
+
$this->data['node_list_count']++;
|
576 |
+
if ($loop == $post['show_element'] ){
|
577 |
+
$_SESSION['pmxi_import']['xml'] = $xml;
|
578 |
+
$this->data['dom'] = $dom;
|
579 |
+
}
|
580 |
+
else unset($dom, $xpath, $elements);
|
581 |
+
$loop++;
|
582 |
+
}
|
583 |
+
}
|
584 |
+
}
|
585 |
+
unset($file);
|
586 |
+
}
|
587 |
+
if ( ! $this->data['node_list_count']) {
|
588 |
+
$this->errors->add('form-validation', __('No matching elements found for XPath expression specified', 'pmxi_plugin'));
|
589 |
+
}
|
590 |
+
}
|
591 |
+
else{ // in default mode
|
592 |
+
$this->data['elements'] = $elements = @ $xpath->query($post['xpath']); // prevent parsing warning to be displayed
|
593 |
+
$this->data['node_list_count'] = $elements->length;
|
594 |
+
if (FALSE === $elements) {
|
595 |
+
$this->errors->add('form-validation', __('Invalid XPath expression', 'pmxi_plugin'));
|
596 |
+
} elseif ( ! $elements->length) {
|
597 |
+
$this->errors->add('form-validation', __('No matching elements found for XPath expression specified', 'pmxi_plugin'));
|
598 |
+
} else {
|
599 |
+
foreach ($elements as $el) {
|
600 |
+
if ( ! $el instanceof DOMElement) {
|
601 |
+
$this->errors->add('form-validation', __('XPath must match only elements', 'pmxi_plugin'));
|
602 |
+
break;
|
603 |
+
};
|
604 |
+
}
|
605 |
}
|
606 |
}
|
607 |
}
|
608 |
if ( ! $this->errors->get_error_codes()) {
|
609 |
+
|
610 |
+
//$this->shrink_xml_element($this->data['dom']->documentElement);
|
611 |
$xpath = new DOMXPath($this->data['dom']);
|
612 |
+
$this->data['elements'] = $elements = @ $xpath->query($post['xpath']); // prevent parsing warning to be displayed
|
613 |
|
614 |
$paths = array(); $this->data['paths'] =& $paths;
|
615 |
+
if (PMXI_Plugin::getInstance()->getOption('highlight_limit') and $elements->length <= PMXI_Plugin::getInstance()->getOption('highlight_limit')) {
|
616 |
+
foreach ($elements as $el) {
|
617 |
if ( ! $el instanceof DOMElement) continue;
|
618 |
|
619 |
$p = $this->get_xml_path($el, $xpath) and $paths[] = $p;
|
637 |
'content' => '',
|
638 |
'name' => '',
|
639 |
'is_keep_linebreaks' => 0,
|
640 |
+
'is_leave_html' => 0
|
641 |
+
);
|
642 |
if ($this->isWizard) {
|
643 |
$this->data['post'] = $post = $this->input->post(
|
644 |
(isset($_SESSION['pmxi_import']['template']) ? $_SESSION['pmxi_import']['template'] : array())
|
645 |
+ $default
|
646 |
);
|
647 |
+
} else {
|
648 |
$this->data['post'] = $post = $this->input->post(
|
649 |
$this->data['import']->template
|
650 |
+ $default
|
651 |
+
);
|
652 |
+
}
|
653 |
|
654 |
if (($load_template = $this->input->post('load_template'))) { // init form with template selected
|
655 |
if ( ! $template->getById($load_template)->isEmpty()) {
|
656 |
$this->data['post'] = array(
|
657 |
'title' => $template->title,
|
658 |
'content' => $template->content,
|
659 |
+
'is_keep_linebreaks' => $template->is_keep_linebreaks,
|
660 |
+
'is_leave_html' => $template->is_leave_html,
|
661 |
'name' => '', // template is always empty
|
662 |
);
|
663 |
$_SESSION['pmxi_import']['is_loaded_template'] = $load_template;
|
671 |
} else {
|
672 |
$this->_validate_template($post['title'], 'Post title');
|
673 |
}
|
674 |
+
|
675 |
if (empty($post['content'])) {
|
676 |
$this->errors->add('form-validation', __('Post content is empty', 'pmxi_plugin'));
|
677 |
} else {
|
678 |
$this->_validate_template($post['content'], 'Post content');
|
679 |
+
}
|
|
|
680 |
|
681 |
+
if ( ! $this->errors->get_error_codes()) {
|
682 |
if ( ! empty($post['name'])) { // save template in database
|
683 |
$template->getByName($post['name'])->set($post)->save();
|
684 |
+
$_SESSION['pmxi_import']['saved_template'] = $template->id;
|
685 |
}
|
686 |
if ($this->isWizard) {
|
687 |
+
$_SESSION['pmxi_import']['template'] = $post;
|
688 |
wp_redirect(add_query_arg('action', 'options', $this->baseUrl)); die();
|
689 |
+
} else {
|
690 |
$this->data['import']->set('template', $post)->save();
|
691 |
wp_redirect(add_query_arg(array('page' => 'pmxi-admin-manage', 'pmlc_nt' => urlencode(__('Template updated', 'pmxi_plugin'))) + array_intersect_key($_GET, array_flip($this->baseUrlParamNames)), admin_url('admin.php'))); die();
|
692 |
}
|
703 |
wp_enqueue_script('quicktags');
|
704 |
$this->render();
|
705 |
}
|
706 |
+
|
707 |
protected function _validate_template($text, $field_title)
|
708 |
{
|
709 |
try {
|
720 |
* Preview selected xml tag (called with ajax from `template` step)
|
721 |
*/
|
722 |
public function tag()
|
723 |
+
{
|
|
|
|
|
724 |
|
725 |
+
$wp_uploads = wp_upload_dir();
|
726 |
+
|
727 |
+
if (empty($this->data['elements']->length))
|
728 |
+
{
|
729 |
$update_previous = new PMXI_Import_Record();
|
730 |
if ($update_previous->getById($this->input->get('id'))) {
|
731 |
$_SESSION['pmxi_import'] = array(
|
734 |
'template' => $update_previous->template,
|
735 |
'options' => $update_previous->options,
|
736 |
);
|
737 |
+
$history = new PMXI_File_List();
|
738 |
+
$history->setColumns('id', 'name', 'registered_on', 'path')->getBy(array('import_id' => $update_previous->id), 'id DESC');
|
739 |
+
if ($history->count()){
|
740 |
+
$history_file = new PMXI_File_Record();
|
741 |
+
$history_file->getBy('id', $history[0]['id']);
|
742 |
+
|
743 |
+
if ($update_previous->large_import == 'Yes'){
|
744 |
+
$_SESSION['pmxi_import']['filePath'] = $history_file->path;
|
745 |
+
$_SESSION['pmxi_import']['source']['root_element'] = $update_previous->root_element;
|
746 |
+
$_SESSION['pmxi_import']['large_file'] = true;
|
747 |
+
$_SESSION['pmxi_import']['count'] = $update_previous->count;
|
748 |
+
}
|
749 |
+
else{
|
750 |
+
$_SESSION['pmxi_import']['xml'] = @file_get_contents($history_file->path);
|
751 |
+
$this->data['dom'] = $dom = new DOMDocument('1.0', 'UTF-8');
|
752 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $_SESSION['pmxi_import']['xml']));
|
753 |
+
$xpath = new DOMXPath($dom);
|
754 |
+
|
755 |
+
$this->data['elements'] = $elements = $xpath->query($update_previous->xpath);
|
756 |
+
if ( !$elements->length ) $this->data['elements'] = $elements = $xpath->query('.');
|
757 |
+
}
|
758 |
+
}
|
759 |
+
|
760 |
} else {
|
761 |
$_SESSION['pmxi_import']['update_previous'] = '';
|
762 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
763 |
}
|
764 |
|
765 |
+
$this->data['tagno'] = min(max(intval($this->input->getpost('tagno', 1)), 1), ( ! $_SESSION['pmxi_import']['large_file'] ) ? $this->data['elements']->length : $_SESSION['pmxi_import']['count']);
|
766 |
+
|
767 |
+
if ($_SESSION['pmxi_import']['large_file'] and $this->data['tagno']){
|
768 |
+
$loop = 1;
|
769 |
+
$_SESSION['pmxi_import']['local_paths'] = (!empty($_SESSION['pmxi_import']['local_paths'])) ? $_SESSION['pmxi_import']['local_paths'] : array($_SESSION['pmxi_import']['filePath']);
|
770 |
+
foreach ($_SESSION['pmxi_import']['local_paths'] as $key => $path) {
|
771 |
+
$file = new PMXI_Chunk($path, array('element' => $_SESSION['pmxi_import']['source']['root_element']));
|
772 |
+
// loop through the file until all lines are read
|
773 |
+
while ($xml = $file->read()) {
|
774 |
+
if (!empty($xml))
|
775 |
+
{
|
776 |
+
PMXI_Import_Record::preprocessXml($xml);
|
777 |
+
|
778 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
779 |
+
$old = libxml_use_internal_errors(true);
|
780 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
781 |
+
libxml_use_internal_errors($old);
|
782 |
+
$xpath = new DOMXPath($dom);
|
783 |
+
if (($this->data['elements'] = $elements = @$xpath->query($_SESSION['pmxi_import']['xpath'])) and $elements->length){
|
784 |
+
if ($loop == $this->data['tagno']){
|
785 |
+
$_SESSION['pmxi_import']['xml'] = $xml;
|
786 |
+
break;
|
787 |
+
} else unset($dom, $xpath, $elements);
|
788 |
+
$loop++;
|
789 |
+
}
|
790 |
+
}
|
791 |
+
}
|
792 |
+
unset($file);
|
793 |
+
}
|
794 |
+
}
|
795 |
+
|
796 |
$this->render();
|
797 |
}
|
798 |
|
805 |
'title' => '',
|
806 |
'content' => '',
|
807 |
'is_keep_linebreaks' => 0,
|
808 |
+
'is_leave_html' => 0
|
809 |
+
));
|
810 |
+
$wp_uploads = wp_upload_dir();
|
811 |
+
|
812 |
+
$tagno = min(max(intval($this->input->getpost('tagno', 1)), 1), ( ! $_SESSION['pmxi_import']['large_file']) ? $this->data['elements']->length : $_SESSION['pmxi_import']['count']);
|
813 |
+
if ($_SESSION['pmxi_import']['large_file']){
|
814 |
+
$loop = 1;
|
815 |
+
foreach ($_SESSION['pmxi_import']['local_paths'] as $key => $path) {
|
816 |
+
$file = new PMXI_Chunk($path, array('element' => $_SESSION['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path']));
|
817 |
+
// loop through the file until all lines are read
|
818 |
+
while ($xml = $file->read()) {
|
819 |
+
if (!empty($xml))
|
820 |
+
{
|
821 |
+
PMXI_Import_Record::preprocessXml($xml);
|
822 |
+
|
823 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
824 |
+
$old = libxml_use_internal_errors(true);
|
825 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
826 |
+
libxml_use_internal_errors($old);
|
827 |
+
$xpath = new DOMXPath($dom);
|
828 |
+
if (($this->data['elements'] = $elements = @$xpath->query($_SESSION['pmxi_import']['xpath'])) and $elements->length){
|
829 |
+
if ( $loop == $tagno ) {
|
830 |
+
$_SESSION['pmxi_import']['xml'] = $xml;
|
831 |
+
break;
|
832 |
+
}
|
833 |
+
unset($dom, $xpath, $elements);
|
834 |
+
$loop++;
|
835 |
+
}
|
836 |
+
}
|
837 |
+
}
|
838 |
+
unset($file);
|
839 |
+
}
|
840 |
+
$tagno = 1;
|
841 |
+
}
|
842 |
+
$xpath = "(" . $_SESSION['pmxi_import']['xpath'] . ")[$tagno]";
|
843 |
// validate
|
844 |
try {
|
|
|
845 |
if (empty($post['title'])) {
|
846 |
$this->errors->add('form-validation', __('Post title is empty', 'pmxi_plugin'));
|
847 |
} else {
|
849 |
if ( ! isset($this->data['title']) or '' == strval(trim(strip_tags($this->data['title'], '<img><input><textarea><iframe><object><embed>')))) {
|
850 |
$this->errors->add('xml-parsing', __('<strong>Warning</strong>: resulting post title is empty', 'pmxi_plugin'));
|
851 |
}
|
852 |
+
else $this->data['title'] = ($post['is_leave_html']) ? utf8_encode(html_entity_decode($this->data['title'])) : $this->data['title'];
|
853 |
}
|
854 |
} catch (XmlImportException $e) {
|
855 |
$this->errors->add('form-validation', sprintf(__('Error parsing title: %s', 'pmxi_plugin'), $e->getMessage()));
|
856 |
}
|
857 |
+
try {
|
858 |
if (empty($post['content'])) {
|
859 |
$this->errors->add('form-validation', __('Post content is empty', 'pmxi_plugin'));
|
860 |
} else {
|
862 |
if ( ! isset($this->data['content']) or '' == strval(trim(strip_tags($this->data['content'], '<img><input><textarea><iframe><object><embed>')))) {
|
863 |
$this->errors->add('xml-parsing', __('<strong>Warning</strong>: resulting post content is empty', 'pmxi_plugin'));
|
864 |
}
|
865 |
+
else $this->data['content'] = ($post['is_leave_html']) ? utf8_encode(html_entity_decode($this->data['content'])) : $this->data['content'];
|
866 |
}
|
867 |
} catch (XmlImportException $e) {
|
868 |
$this->errors->add('form-validation', sprintf(__('Error parsing content: %s', 'pmxi_plugin'), $e->getMessage()));
|
883 |
if ($this->isWizard) {
|
884 |
$this->data['source_type'] = $_SESSION['pmxi_import']['source']['type'];
|
885 |
$default['unique_key'] = $_SESSION['pmxi_import']['template']['title'];
|
886 |
+
|
887 |
+
// auto searching ID element
|
888 |
+
if (!empty($this->data['dom'])){
|
889 |
+
$this->find_unique_key($this->data['dom']->documentElement);
|
890 |
+
if (!empty($this->_unique_key)){
|
891 |
+
$id_finded = false;
|
892 |
+
foreach ($this->_unique_key as $key) {
|
893 |
+
if (stripos($key, 'id') !== false) {
|
894 |
+
$default['unique_key'] .= ' - {'.$key.'[1]}';
|
895 |
+
$id_finded = true;
|
896 |
+
break;
|
897 |
+
}
|
898 |
+
}
|
899 |
+
if (!$id_finded){
|
900 |
+
foreach ($this->_unique_key as $key) {
|
901 |
+
if (stripos($key, 'url') !== false) {
|
902 |
+
$default['unique_key'] .= ' - {'.$key.'[1]}';
|
903 |
+
$id_finded = true;
|
904 |
+
break;
|
905 |
+
}
|
906 |
+
}
|
907 |
+
}
|
908 |
+
}
|
909 |
+
}
|
910 |
+
|
911 |
$post = $this->input->post(
|
912 |
(isset($_SESSION['pmxi_import']['options']) ? $_SESSION['pmxi_import']['options'] : array())
|
913 |
+ $default
|
914 |
);
|
915 |
|
916 |
$scheduled = $this->input->post(array(
|
917 |
+
'is_scheduled' => ! empty($_SESSION['pmxi_import']['scheduled']),
|
918 |
+
'scheduled_period' => ! empty($_SESSION['pmxi_import']['scheduled']) ? $_SESSION['pmxi_import']['scheduled'] : '0 0 * * *', // daily by default
|
919 |
));
|
920 |
+
|
921 |
} else {
|
922 |
$this->data['source_type'] = $this->data['import']->type;
|
923 |
$post = $this->input->post(
|
929 |
'scheduled_period' => ! empty($this->data['import']->scheduled) ? $this->data['import']->scheduled : '0 0 * * *', // daily by default
|
930 |
));
|
931 |
}
|
932 |
+
|
933 |
$this->data['post'] =& $post;
|
934 |
$this->data['scheduled'] =& $scheduled;
|
935 |
$this->data['is_loaded_template'] = $_SESSION['pmxi_import']['is_loaded_template'];
|
936 |
|
937 |
+
// Get All meta keys in the system
|
938 |
+
$this->data['meta_keys'] = $keys = new PMXI_Model_List();
|
939 |
+
$keys->setTable(PMXI_Plugin::getInstance()->getWPPrefix() . 'postmeta');
|
940 |
+
$keys->setColumns('meta_id', 'meta_key')->getBy(NULL, "meta_id", NULL, NULL, "meta_key");
|
941 |
+
|
942 |
if (($load_options = $this->input->post('load_options'))) { // init form with template selected
|
943 |
$this->data['load_options'] = true;
|
944 |
$template = new PMXI_Template_Record();
|
945 |
+
if ( ! $template->getById($this->data['is_loaded_template'])->isEmpty()) {
|
946 |
+
$post = (!empty($template->options) ? $template->options : array()) + $default;
|
947 |
$scheduled = array(
|
948 |
'is_scheduled' => ! empty($template->scheduled),
|
949 |
'scheduled_period' => ! empty($template->scheduled) ? $template->scheduled : '0 0 * * *', // daily by default
|
954 |
$post = $default;
|
955 |
$scheduled = $this->input->post(array(
|
956 |
'is_scheduled' => ! empty($post['scheduled']),
|
957 |
+
'scheduled_period' => ! empty($post['scheduled']) ? $post['scheduled_period'] : '0 0 * * *', // daily by default
|
958 |
));
|
959 |
} elseif ($this->input->post('is_submitted')) {
|
960 |
+
check_admin_referer('options', '_wpnonce_options');
|
961 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
962 |
if ('page' == $post['type'] and ! preg_match('%^(-?\d+)?$%', $post['order'])) {
|
963 |
$this->errors->add('form-validation', __('Order must be an integer number', 'pmxi_plugin'));
|
964 |
}
|
984 |
if ( ! preg_match('%^([1-9]\d*)( *- *([1-9]\d*))?$%', $chank, $mtch)) {
|
985 |
$this->errors->add('form-validation', __('Wrong format of `Import only specified records` value', 'pmxi_plugin'));
|
986 |
break;
|
987 |
+
} elseif ($this->isWizard and empty($_SESSION['pmxi_import']['large_file']) and (intval($mtch[1]) > $this->data['elements']->length or isset($mtch[3]) and intval($mtch[3]) > $this->data['elements']->length)) {
|
988 |
$this->errors->add('form-validation', __('One of the numbers in `Import only specified records` value exceeds record quantity in XML file', 'pmxi_plugin'));
|
989 |
break;
|
990 |
}
|
996 |
} else {
|
997 |
$this->_validate_template($post['unique_key'], __('Post Unique Key', 'pmxi_plugin'));
|
998 |
}
|
999 |
+
if ( $post['is_duplicates'] and 'custom field' == $post['duplicate_indicator']){
|
1000 |
+
if ('' == $post['custom_duplicate_name'])
|
1001 |
+
$this->errors->add('form-validation', __('Custom field name must be specified.', 'pmxi_plugin'));
|
1002 |
+
if ('' == $post['custom_duplicate_value'])
|
1003 |
+
$this->errors->add('form-validation', __('Custom field value must be specified.', 'pmxi_plugin'));
|
1004 |
+
}
|
1005 |
|
1006 |
if ( ! $this->errors->get_error_codes()) { // no validation errors found
|
1007 |
// assign some defaults
|
1040 |
'template' => $_SESSION['pmxi_import']['template'],
|
1041 |
'options' => $_SESSION['pmxi_import']['options'],
|
1042 |
'scheduled' => $_SESSION['pmxi_import']['scheduled'],
|
1043 |
+
'count' => $_SESSION['pmxi_import']['count'],
|
1044 |
+
'friendly_name' => $this->data['post']['friendly_name'],
|
1045 |
)
|
1046 |
)->save();
|
1047 |
|
1049 |
$history_file->set(array(
|
1050 |
'name' => $import->name,
|
1051 |
'import_id' => $import->id,
|
1052 |
+
'path' => $_SESSION['pmxi_import']['filePath'],
|
1053 |
'contents' => $_SESSION['pmxi_import']['xml'],
|
1054 |
'registered_on' => date('Y-m-d H:i:s'),
|
1055 |
))->save();
|
1057 |
wp_redirect(add_query_arg(array('page' => 'pmxi-admin-manage', 'pmlc_nt' => urlencode($is_update ? __('Import updated', 'pmxi_plugin') : __('Import created', 'pmxi_plugin'))), admin_url('admin.php'))); die();
|
1058 |
}
|
1059 |
} else {
|
1060 |
+
|
1061 |
+
$this->data['import']->set('options', $post)->set( array( 'scheduled' => $scheduled['is_scheduled'] ? $scheduled['scheduled_period'] : '', 'friendly_name' => $this->data['post']['friendly_name'] ) )->save();
|
1062 |
$template = new PMXI_Template_Record();
|
1063 |
|
1064 |
if (!$template->getByName($this->data['import']->template['name'])->isEmpty()){
|
1069 |
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();
|
1070 |
}
|
1071 |
}
|
1072 |
+
}
|
|
|
|
|
1073 |
|
1074 |
$this->render();
|
1075 |
}
|
1077 |
/**
|
1078 |
* Import processing step (status console)
|
1079 |
*/
|
1080 |
+
public function process($save_history = true)
|
1081 |
{
|
1082 |
+
$wp_uploads = wp_upload_dir();
|
|
|
|
|
|
|
1083 |
|
1084 |
+
set_time_limit(0);
|
1085 |
+
|
1086 |
+
$import = $this->data['update_previous'];
|
1087 |
$import->set(
|
1088 |
+
(empty($_SESSION['pmxi_import']['source']) ? array() : $_SESSION['pmxi_import']['source'])
|
1089 |
+ array(
|
1090 |
'xpath' => $_SESSION['pmxi_import']['xpath'],
|
1091 |
'template' => $_SESSION['pmxi_import']['template'],
|
1092 |
+
'options' => $_SESSION['pmxi_import']['options'],
|
1093 |
+
'scheduled' => $_SESSION['pmxi_import']['scheduled'],
|
1094 |
+
'count' => $_SESSION['pmxi_import']['count'],
|
1095 |
+
'friendly_name' => $_SESSION['pmxi_import']['options']['friendly_name'],
|
1096 |
)
|
1097 |
+
);
|
1098 |
+
|
1099 |
+
if ( ! PMXI_Plugin::is_ajax()) {
|
1100 |
+
|
1101 |
+
$this->render();
|
1102 |
+
wp_ob_end_flush_all(); flush();
|
1103 |
+
|
1104 |
+
// Save import history
|
1105 |
+
if ( $_SESSION['pmxi_import']['chunk_number'] === 1 ){
|
1106 |
+
// store import info in database
|
1107 |
+
$import->save();
|
1108 |
+
|
1109 |
+
if ($_SESSION['pmxi_import']['large_file']) $_SESSION['pmxi_import']['update_previous'] = $import->id;
|
1110 |
+
|
1111 |
+
if ($save_history){
|
1112 |
+
$history_file = new PMXI_File_Record();
|
1113 |
+
$history_file->set(array(
|
1114 |
+
'name' => $import->name,
|
1115 |
+
'import_id' => $import->id,
|
1116 |
+
'path' => $_SESSION['pmxi_import']['filePath'],
|
1117 |
+
'contents' => $_SESSION['pmxi_import']['xml'],
|
1118 |
+
'registered_on' => date('Y-m-d H:i:s'),
|
1119 |
+
))->save();
|
1120 |
+
}
|
1121 |
+
}
|
1122 |
+
}
|
1123 |
+
|
1124 |
+
// create chunks
|
1125 |
+
if ($_SESSION['pmxi_import']['large_file'] and $_SESSION['pmxi_import']['chunk_number'] === 1 and $_SESSION['pmxi_import']['options']['create_chunks'] and ! PMXI_Plugin::is_ajax()){
|
1126 |
+
|
1127 |
+
$_SESSION['pmxi_import']['chunks_files'] = array();
|
1128 |
+
|
1129 |
+
foreach ($_SESSION['pmxi_import']['local_paths'] as $key => $path) {
|
1130 |
+
$file = new PMXI_Chunk($path, array('element' => $_SESSION['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path']));
|
1131 |
+
$new_chunk = true;
|
1132 |
+
$loop = 0;
|
1133 |
+
$o = false;
|
1134 |
+
|
1135 |
+
// loop through the file until all lines are read
|
1136 |
+
while ($xml = $file->read()) {
|
1137 |
+
|
1138 |
+
if (!empty($xml))
|
1139 |
+
{
|
1140 |
+
|
1141 |
+
PMXI_Import_Record::preprocessXml($xml);
|
1142 |
+
|
1143 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
1144 |
+
$old = libxml_use_internal_errors(true);
|
1145 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
1146 |
+
libxml_use_internal_errors($old);
|
1147 |
+
$xpath = new DOMXPath($dom);
|
1148 |
+
if (($elements = @$xpath->query($_SESSION['pmxi_import']['xpath'])) and $elements->length){
|
1149 |
+
|
1150 |
+
if ($new_chunk){
|
1151 |
+
$tmpname = $wp_uploads['path'] .'/'. wp_unique_filename($wp_uploads['path'], basename($path));
|
1152 |
+
$c = fopen($tmpname, 'w');
|
1153 |
+
fwrite($c, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<".$_SESSION['pmxi_import']['source']['root_element'] ."s>\n");
|
1154 |
+
}
|
1155 |
+
|
1156 |
+
fwrite($c, $xml . "\n");
|
1157 |
+
|
1158 |
+
if ($loop == $_SESSION['pmxi_import']['options']['records_per_request'] - 1) {
|
1159 |
+
fwrite($c, "</".$_SESSION['pmxi_import']['source']['root_element'] . "s>");
|
1160 |
+
fclose($c);
|
1161 |
+
$_SESSION['pmxi_import']['chunks_files'][] = $tmpname;
|
1162 |
+
|
1163 |
+
$loop = 0;
|
1164 |
+
$new_chunk = true;
|
1165 |
+
}
|
1166 |
+
else {
|
1167 |
+
$loop++;
|
1168 |
+
$new_chunk = false;
|
1169 |
+
}
|
1170 |
+
}
|
1171 |
+
}
|
1172 |
+
}
|
1173 |
+
if ($loop){
|
1174 |
+
fwrite($c, "</".$_SESSION['pmxi_import']['source']['root_element'] . "s>");
|
1175 |
+
fclose($c);
|
1176 |
+
$_SESSION['pmxi_import']['chunks_files'][] = $tmpname;
|
1177 |
+
}
|
1178 |
+
}
|
1179 |
+
$_SESSION['pmxi_import']['local_paths'] = $_SESSION['pmxi_import']['chunks_files'];
|
1180 |
+
|
1181 |
+
}
|
1182 |
+
|
1183 |
+
$logger = create_function('$m', 'echo "<div class=\\"progress-msg\\">$m</div>\\n"; if ( "" != strip_tags(pmxi_strip_tags_content($m))) { $_SESSION[\'pmxi_import\'][\'log\'] .= "<p>".strip_tags(pmxi_strip_tags_content($m))."</p>"; flush(); }');
|
1184 |
+
|
1185 |
+
$_SESSION['pmxi_import']['start_time'] = (empty($_SESSION['pmxi_import']['start_time'])) ? time() : $_SESSION['pmxi_import']['start_time'];
|
1186 |
|
1187 |
+
in_array($import->type, array('ftp')) and !PMXI_Plugin::is_ajax() and $logger and call_user_func($logger, __('Reading files for import...', 'pmxi_plugin'));
|
1188 |
+
in_array($import->type, array('ftp')) and !PMXI_Plugin::is_ajax() and $logger and call_user_func($logger, sprintf(_n('%s file found', '%s files found', count($_SESSION['pmxi_import']['local_paths']), 'pmxi_plugin'), count($_SESSION['pmxi_import']['local_paths'])));
|
1189 |
+
in_array($import->type, array('ftp')) and !PMXI_Plugin::is_ajax() and $logger and call_user_func($logger, sprintf(__('Importing %s (%s of %s)', 'pmxi_plugin'), $_SESSION['pmxi_import']['local_paths'][0], 1, count($_SESSION['pmxi_import']['local_paths'])));
|
1190 |
|
1191 |
+
if (empty($_SESSION['pmxi_import']['large_file'])){
|
1192 |
+
$import->process($_SESSION['pmxi_import']['xml'], $logger, false);
|
|
|
|
|
1193 |
}
|
1194 |
+
elseif (PMXI_Plugin::is_ajax()) {
|
1195 |
+
|
1196 |
+
$_SESSION['pmxi_import']['current_post_ids'] = (empty($_SESSION['pmxi_import']['current_post_ids'])) ? array() : $_SESSION['pmxi_import']['current_post_ids'];
|
1197 |
+
|
1198 |
+
$_SESSION['pmxi_import']['pointer'] = (empty($_SESSION['pmxi_import']['pointer'])) ? 0 : $_SESSION['pmxi_import']['pointer'];
|
1199 |
+
|
1200 |
+
$loop = 0;
|
1201 |
+
|
1202 |
+
foreach ($_SESSION['pmxi_import']['local_paths'] as $key => $path) {
|
1203 |
+
|
1204 |
+
if ($_SESSION['pmxi_import']['options']['create_chunks'] and $_SESSION['pmxi_import']['action'] != 'continue'){
|
1205 |
+
|
1206 |
+
ob_start();
|
1207 |
+
|
1208 |
+
$xml = file_get_contents($path);
|
1209 |
+
|
1210 |
+
if (!empty($xml))
|
1211 |
+
{
|
1212 |
+
PMXI_Import_Record::preprocessXml($xml);
|
1213 |
+
|
1214 |
+
$import->set(array('xpath' => '/' . $_SESSION['pmxi_import']['source']['root_element'] . 's' . $_SESSION['pmxi_import']['xpath']))->save();
|
1215 |
+
$import->process($xml, $logger, $_SESSION['pmxi_import']['chunk_number']);
|
1216 |
+
$import->set(array('xpath' => $_SESSION['pmxi_import']['xpath']))->save();
|
1217 |
+
|
1218 |
+
array_shift($_SESSION['pmxi_import']['local_paths']);
|
1219 |
+
if (!empty($_SESSION['pmxi_import']['chunks_files'])) {
|
1220 |
+
$imported_file = array_shift($_SESSION['pmxi_import']['chunks_files']);
|
1221 |
+
@unlink($imported_file);
|
1222 |
+
}
|
1223 |
+
}
|
1224 |
+
|
1225 |
+
exit(ob_get_clean());
|
1226 |
+
}
|
1227 |
+
else{
|
1228 |
+
|
1229 |
+
$file = new PMXI_Chunk($path, array('element' => $_SESSION['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path']), $_SESSION['pmxi_import']['pointer']);
|
1230 |
+
|
1231 |
+
// loop through the file until all lines are read
|
1232 |
+
while ($xml = $file->read()) {
|
1233 |
+
|
1234 |
+
if (!empty($xml))
|
1235 |
+
{
|
1236 |
+
PMXI_Import_Record::preprocessXml($xml);
|
1237 |
+
|
1238 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
1239 |
+
$old = libxml_use_internal_errors(true);
|
1240 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
1241 |
+
libxml_use_internal_errors($old);
|
1242 |
+
$xpath = new DOMXPath($dom);
|
1243 |
+
if (($this->data['elements'] = $elements = @$xpath->query($_SESSION['pmxi_import']['xpath'])) and $elements->length){
|
1244 |
+
$_SESSION['pmxi_import']['pointer'] = $file->pointer;
|
1245 |
+
$_SESSION['pmxi_import']['xml'] = $xml;
|
1246 |
+
if ( ! $loop ) ob_start();
|
1247 |
+
$import->process($_SESSION['pmxi_import']['xml'], $logger, $_SESSION['pmxi_import']['chunk_number']);
|
1248 |
+
if ( $loop == $_SESSION['pmxi_import']['options']['records_per_request'] - 1 ) exit(ob_get_clean());
|
1249 |
+
$loop++;
|
1250 |
+
}
|
1251 |
+
}
|
1252 |
+
|
1253 |
+
if ($_SESSION['pmxi_import']['created_records'] + $_SESSION['pmxi_import']['updated_records'] == $_SESSION['pmxi_import']['count']){
|
1254 |
+
array_shift($_SESSION['pmxi_import']['local_paths']);
|
1255 |
+
exit(ob_get_clean());
|
1256 |
+
}
|
1257 |
+
|
1258 |
+
$_SESSION['pmxi_import']['pointer'] = 0;
|
1259 |
+
|
1260 |
+
in_array($import->type,array('ftp')) and !empty($_SESSION['pmxi_import']['local_paths']) and $logger and call_user_func($logger, sprintf(__('Importing %s', 'pmxi_plugin'), $_SESSION['pmxi_import']['local_paths'][0]));
|
1261 |
+
|
1262 |
+
}
|
1263 |
+
}
|
1264 |
+
}
|
1265 |
+
}
|
1266 |
+
|
1267 |
+
do_action( 'pmxi_after_xml_import' );
|
1268 |
|
1269 |
+
if (! $_SESSION['pmxi_import']['large_file'] or PMXI_Plugin::is_ajax()){
|
1270 |
+
|
1271 |
+
// Save import process log
|
1272 |
+
$log_file = $wp_uploads['basedir'] . '/wpallimport_logs/' . $import->id . '.html';
|
1273 |
+
if (file_exists($log_file)) unlink($log_file);
|
1274 |
+
@file_put_contents($log_file, $_SESSION['pmxi_import']['log']);
|
1275 |
+
|
1276 |
+
// clear import session
|
1277 |
+
unset($_SESSION['pmxi_import']); // clear session data (prevent from reimporting the same data on page refresh)
|
1278 |
|
1279 |
// [indicate in header process is complete]
|
1280 |
+
$msg = addcslashes(__('Complete', 'pmxi_plugin'), "'\n\r");
|
1281 |
+
|
1282 |
+
ob_start();
|
1283 |
+
|
1284 |
+
echo '<a id="download_pmxi_log" class="update" href="'.esc_url(add_query_arg(array('id' => $import->id, 'action' => 'log', 'page' => 'pmxi-admin-manage'), $this->baseUrl)).'">Download log</a>';
|
1285 |
echo <<<COMPLETE
|
1286 |
<script type="text/javascript">
|
1287 |
//<![CDATA[
|
1288 |
(function($){
|
1289 |
+
var percents = $('.import_percent:last').html();
|
1290 |
+
if (percents != null && percents != ''){
|
1291 |
+
$('#center_progress').html($('.import_process_bar:last').html());
|
1292 |
+
$('#right_progress').html(percents + '%');
|
1293 |
+
$('#progressbar div').css({'width': ((parseInt(percents) > 100) ? 100 : percents) + '%'});
|
1294 |
+
}
|
1295 |
$('#status').html('$msg');
|
1296 |
window.onbeforeunload = false;
|
1297 |
})(jQuery);
|
1298 |
//]]>
|
1299 |
</script>
|
1300 |
COMPLETE;
|
1301 |
+
// [/indicate in header process is complete]
|
|
|
1302 |
|
1303 |
+
echo ob_get_clean(); die;
|
1304 |
+
|
1305 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1306 |
}
|
1307 |
|
1308 |
protected $_sibling_limit = 20;
|
1361 |
}
|
1362 |
protected function render_xml_element(DOMElement $el, $shorten = false, $path = '/', $ind = 1, $lvl = 0)
|
1363 |
{
|
1364 |
+
$path .= $el->nodeName;
|
1365 |
if ( ! $el->parentNode instanceof DOMDocument and $ind > 0) {
|
1366 |
$path .= "[$ind]";
|
1367 |
+
}
|
1368 |
|
1369 |
echo '<div class="xml-element lvl-' . $lvl . ' lvl-mod4-' . ($lvl % 4) . '" title="' . $path . '">';
|
1370 |
if ($el->hasChildNodes()) {
|
1399 |
}
|
1400 |
echo '</div>';
|
1401 |
}
|
1402 |
+
protected $_unique_key = array();
|
1403 |
+
protected function find_unique_key(DOMElement $el){
|
1404 |
+
if ($el->hasChildNodes()) {
|
1405 |
+
if ($el->childNodes->length) {
|
1406 |
+
foreach ($el->childNodes as $child) {
|
1407 |
+
if ($child instanceof DOMElement) {
|
1408 |
+
if (!in_array($child->nodeName, $this->_unique_key)) $this->_unique_key[] = $child->nodeName;
|
1409 |
+
$this->find_unique_key($child);
|
1410 |
+
}
|
1411 |
+
}
|
1412 |
+
}
|
1413 |
+
}
|
1414 |
+
}
|
1415 |
protected function render_xml_text($text, $shorten = false, $is_render_collapsed = false)
|
1416 |
{
|
1417 |
if (empty($text)) {
|
1543 |
|
1544 |
return NULL;
|
1545 |
}
|
1546 |
+
|
1547 |
+
protected function sxml_append(SimpleXMLElement $to, SimpleXMLElement $from) {
|
1548 |
+
$toDom = dom_import_simplexml($to);
|
1549 |
+
$fromDom = dom_import_simplexml($from);
|
1550 |
+
$toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true));
|
1551 |
+
}
|
1552 |
|
1553 |
}
|
controllers/admin/manage.php
CHANGED
@@ -22,7 +22,7 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
|
|
22 |
|
23 |
$get = $this->input->get(array(
|
24 |
's' => '',
|
25 |
-
'order_by' => '
|
26 |
'order' => 'DESC',
|
27 |
'pagenum' => 1,
|
28 |
'perPage' => 10,
|
@@ -55,96 +55,263 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
|
|
55 |
'current' => $pagenum,
|
56 |
));
|
57 |
|
|
|
|
|
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 |
-
|
79 |
-
|
80 |
-
|
81 |
|
82 |
-
|
83 |
|
84 |
-
|
85 |
|
86 |
-
if (
|
87 |
-
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
}
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
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 |
-
|
124 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
}
|
126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
|
@@ -195,4 +362,18 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
|
|
195 |
|
196 |
$this->render();
|
197 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
198 |
}
|
22 |
|
23 |
$get = $this->input->get(array(
|
24 |
's' => '',
|
25 |
+
'order_by' => 'registered_on',
|
26 |
'order' => 'DESC',
|
27 |
'pagenum' => 1,
|
28 |
'perPage' => 10,
|
55 |
'current' => $pagenum,
|
56 |
));
|
57 |
|
58 |
+
unset($_SESSION['pmxi_import']);
|
59 |
+
|
60 |
$this->render();
|
61 |
}
|
62 |
|
63 |
+
/**
|
64 |
+
* Edit Template
|
65 |
+
*/
|
66 |
+
public function edit() {
|
67 |
+
// deligate operation to other controller
|
68 |
+
$controller = new PMXI_Admin_Import();
|
69 |
+
$controller->set('isTemplateEdit', true);
|
70 |
+
$controller->template();
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Edit Options
|
75 |
+
*/
|
76 |
+
public function options() {
|
77 |
+
// deligate operation to other controller
|
78 |
+
$controller = new PMXI_Admin_Import();
|
79 |
+
$controller->set('isTemplateEdit', true);
|
80 |
+
$controller->options();
|
81 |
+
}
|
82 |
+
|
83 |
/**
|
84 |
* Reimport
|
85 |
*/
|
86 |
public function update() {
|
87 |
$id = $this->input->get('id');
|
88 |
+
$action_type = $this->input->get('type');
|
89 |
+
$pointer = 0;
|
90 |
+
|
91 |
$this->data['item'] = $item = new PMXI_Import_Record();
|
92 |
if ( ! $id or $item->getById($id)->isEmpty()) {
|
93 |
wp_redirect($this->baseUrl); die();
|
94 |
+
}
|
95 |
|
96 |
+
unset($_SESSION['pmxi_import']);
|
97 |
+
|
98 |
if ($this->input->post('is_confirmed')) {
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
+
check_admin_referer('update-import', '_wpnonce_update-import');
|
101 |
+
|
102 |
+
$uploads = wp_upload_dir();
|
103 |
|
104 |
+
if ($item->large_import == 'No' or ($item->large_import == 'Yes' and empty($_SESSION['pmxi_import']['chunk_number']))) {
|
105 |
|
106 |
+
if ( in_array($item->type, array('upload')) ) { // if import type NOT URL
|
107 |
|
108 |
+
if (preg_match('%\W(zip)$%i', trim(basename($item->path)))) {
|
109 |
+
|
110 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/pclzip.lib.php');
|
111 |
+
|
112 |
+
$archive = new PclZip(trim($item->path));
|
113 |
+
if (($v_result_list = $archive->extract(PCLZIP_OPT_PATH, $uploads['path'], PCLZIP_OPT_REPLACE_NEWER)) == 0) {
|
114 |
+
$this->errors->add('form-validation', 'Failed to open uploaded ZIP archive : '.$archive->errorInfo(true));
|
115 |
+
}
|
116 |
+
else {
|
117 |
+
|
118 |
+
$filePath = '';
|
119 |
+
|
120 |
+
if (!empty($v_result_list)){
|
121 |
+
foreach ($v_result_list as $unzipped_file) {
|
122 |
+
if ($unzipped_file['status'] == 'ok') $filePath = $unzipped_file['filename'];
|
123 |
+
}
|
124 |
+
}
|
125 |
+
if($uploads['error']){
|
126 |
+
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
127 |
+
}
|
128 |
+
|
129 |
+
if(empty($filePath)){
|
130 |
+
$zip = zip_open(trim($item->path));
|
131 |
+
if (is_resource($zip)) {
|
132 |
+
while ($zip_entry = zip_read($zip)) {
|
133 |
+
$filePath = zip_entry_name($zip_entry);
|
134 |
+
$fp = fopen($uploads['path']."/".$filePath, "w");
|
135 |
+
if (zip_entry_open($zip, $zip_entry, "r")) {
|
136 |
+
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
|
137 |
+
fwrite($fp,"$buf");
|
138 |
+
zip_entry_close($zip_entry);
|
139 |
+
fclose($fp);
|
140 |
+
}
|
141 |
+
break;
|
142 |
+
}
|
143 |
+
zip_close($zip);
|
144 |
+
|
145 |
+
} else {
|
146 |
+
$this->errors->add('form-validation', __('Failed to open uploaded ZIP archive. Can\'t extract files.', 'pmxi_plugin'));
|
147 |
+
}
|
148 |
+
}
|
149 |
|
150 |
+
if (preg_match('%\W(csv)$%i', trim($filePath))){ // If CSV file found in archieve
|
151 |
+
|
152 |
+
if($uploads['error']){
|
153 |
+
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
154 |
+
}
|
155 |
+
if (empty($item->large_import) or $item->large_import == 'No') {
|
156 |
+
$filePath = PMXI_Plugin::csv_to_xml($filePath);
|
157 |
+
}
|
158 |
+
else{
|
159 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
160 |
+
$csv = new PMXI_CsvParser($filePath, true); // create chunks
|
161 |
+
$filePath = $csv->xml_path;
|
162 |
+
}
|
163 |
+
}
|
164 |
+
}
|
165 |
+
|
166 |
+
} elseif ( preg_match('%\W(csv)$%i', trim($item->path))) { // If CSV file uploaded
|
167 |
+
if($uploads['error']){
|
168 |
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
169 |
+
}
|
170 |
+
$filePath = $post['filepath'];
|
171 |
+
if (empty($item->large_import) or $item->large_import == 'No') {
|
172 |
+
$filePath = PMXI_Plugin::csv_to_xml($item->path);
|
173 |
+
} else{
|
174 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
175 |
+
$csv = new PMXI_CsvParser($item->path, true);
|
176 |
+
$filePath = $csv->xml_path;
|
177 |
+
}
|
178 |
+
} elseif(preg_match('%\W(gz)$%i', trim($item->path))){ // If gz file uploaded
|
179 |
+
$fileInfo = pmxi_gzfile_get_contents($item->path);
|
180 |
+
$filePath = $fileInfo['localPath'];
|
181 |
+
// detect CSV or XML
|
182 |
+
if ( $fileInfo['type'] == 'csv') { // it is CSV file
|
183 |
+
if (empty($item->large_import) or $item->large_import == 'No') {
|
184 |
+
$filePath = PMXI_Plugin::csv_to_xml($filePath); // convert CSV to XML
|
185 |
+
}
|
186 |
+
else{
|
187 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
188 |
+
$csv = new PMXI_CsvParser($filePath, true); // create chunks
|
189 |
+
$filePath = $csv->xml_path;
|
190 |
+
}
|
191 |
}
|
192 |
+
} else { // If XML file uploaded
|
193 |
+
|
194 |
+
$filePath = $item->path;
|
195 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
}
|
197 |
|
|
|
|
|
|
|
|
|
|
|
|
|
198 |
}
|
199 |
+
|
200 |
+
if (empty($xml)){
|
201 |
+
|
202 |
+
if ($item->large_import == 'Yes'){
|
203 |
+
|
204 |
+
set_time_limit(0);
|
205 |
+
|
206 |
+
$chunks = 0;
|
207 |
+
|
208 |
+
$chunk_path = '';
|
209 |
+
|
210 |
+
$local_paths = !empty($local_paths) ? $local_paths : array($filePath);
|
211 |
+
|
212 |
+
foreach ($local_paths as $key => $path) {
|
213 |
+
|
214 |
+
$file = new PMXI_Chunk($path, array('element' => $item->root_element, 'path' => $uploads['path']));
|
215 |
+
|
216 |
+
while ($xml = $file->read()) {
|
217 |
+
|
218 |
+
if (!empty($xml))
|
219 |
+
{
|
220 |
+
PMXI_Import_Record::preprocessXml($xml);
|
221 |
+
|
222 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
223 |
+
$old = libxml_use_internal_errors(true);
|
224 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
225 |
+
libxml_use_internal_errors($old);
|
226 |
+
$xpath = new DOMXPath($dom);
|
227 |
+
if (($this->data['elements'] = $elements = @$xpath->query($item->xpath)) and $elements->length) {
|
228 |
+
if ( !$chunks) {
|
229 |
+
$chunk_path = $uploads['path'] .'/'. wp_unique_filename($uploads['path'], "chunk_".basename($path));
|
230 |
+
if (file_exists($chunk_path)) unlink($chunk_path);
|
231 |
+
file_put_contents($chunk_path, '<?xml version="1.0" encoding="utf-8"?>'."\n".$xml);
|
232 |
+
chmod($chunk_path, 0755);
|
233 |
+
}
|
234 |
+
$chunks++;
|
235 |
+
|
236 |
+
if (!empty($action_type) and $action_type == 'continue' and $chunks == $item->imported) $pointer = $file->pointer;
|
237 |
+
|
238 |
+
}
|
239 |
+
unset($dom, $xpath, $elements);
|
240 |
+
}
|
241 |
+
}
|
242 |
+
unset($file);
|
243 |
+
|
244 |
+
!$key and $filePath = $path;
|
245 |
+
}
|
246 |
+
|
247 |
+
if (empty($chunks))
|
248 |
+
$this->errors->add('form-validation', __('No matching elements found for Root element and XPath expression specified', 'pmxi_plugin'));
|
249 |
+
else
|
250 |
+
$xml = @file_get_contents($chunk_path);
|
251 |
+
|
252 |
+
} else {
|
253 |
+
|
254 |
+
ob_start();
|
255 |
+
$filePath && @readgzfile($filePath);
|
256 |
+
$xml = ob_get_clean();
|
257 |
+
|
258 |
+
if (empty($xml)){
|
259 |
+
$xml = @file_get_contents($filePath);
|
260 |
+
if (empty($xml)) get_file_curl($filePath, $uploads['path'] .'/'. basename($filePath));
|
261 |
+
if (empty($xml)) $xml = @file_get_contents($uploads['path'] .'/'. basename($filePath));
|
262 |
+
}
|
263 |
+
}
|
264 |
+
}
|
265 |
}
|
266 |
+
|
267 |
+
if (!empty($_SESSION['pmxi_import']['xml'])) $xml = $_SESSION['pmxi_import']['xml'];
|
268 |
+
|
269 |
+
if ($item->large_import == 'Yes' or PMXI_Import_Record::validateXml($xml, $this->errors)) { // xml is valid
|
270 |
+
|
271 |
+
$item->set(array(
|
272 |
+
'processing' => 0,
|
273 |
+
'queue_chunk_number' => 0,
|
274 |
+
'current_post_ids' => ''
|
275 |
+
))->save();
|
276 |
+
|
277 |
// compose data to look like result of wizard steps
|
278 |
+
$_SESSION['pmxi_import'] = (empty($_SESSION['pmxi_import']['chunk_number'])) ? array(
|
279 |
+
'xml' => (isset($xml)) ? $xml : '',
|
280 |
+
'filePath' => $filePath,
|
281 |
'source' => array(
|
282 |
'name' => $item->name,
|
283 |
+
'type' => $item->type,
|
284 |
'path' => $item->path,
|
285 |
+
'root_element' => $item->root_element,
|
286 |
),
|
287 |
'update_previous' => $item->id,
|
288 |
'xpath' => $item->xpath,
|
289 |
'template' => $item->template,
|
290 |
'options' => $item->options,
|
291 |
+
'scheduled' => $item->scheduled,
|
292 |
+
'current_post_ids' => '',
|
293 |
+
'large_file' => ($item->large_import == 'Yes') ? true : false,
|
294 |
+
'chunk_number' => (!empty($action_type) and $action_type == 'continue') ? $item->imported : 1,
|
295 |
+
'pointer' => $pointer,
|
296 |
+
'log' => '',
|
297 |
+
'created_records' => (!empty($action_type) and $action_type == 'continue') ? $item->created : 0,
|
298 |
+
'updated_records' => (!empty($action_type) and $action_type == 'continue') ? $item->updated : 0,
|
299 |
+
'skipped_records' => (!empty($action_type) and $action_type == 'continue') ? $item->skipped : 0,
|
300 |
+
'warnings' => 0,
|
301 |
+
'errors' => 0,
|
302 |
+
'start_time' => 0,
|
303 |
+
'count' => (isset($chunks)) ? $chunks : 0,
|
304 |
+
'local_paths' => (!empty($local_paths)) ? $local_paths : array(), // ftp import local copies of remote files
|
305 |
+
'action' => (!empty($action_type) and $action_type == 'continue') ? 'continue' : 'update',
|
306 |
+
) : $_SESSION['pmxi_import'];
|
307 |
+
|
308 |
// deligate operation to other controller
|
309 |
$controller = new PMXI_Admin_Import();
|
310 |
$controller->data['update_previous'] = $item;
|
311 |
$controller->process();
|
312 |
return;
|
313 |
}
|
314 |
+
}
|
|
|
315 |
$this->render();
|
316 |
}
|
317 |
|
362 |
|
363 |
$this->render();
|
364 |
}
|
365 |
+
|
366 |
+
/*
|
367 |
+
* Download import log file
|
368 |
+
*
|
369 |
+
*/
|
370 |
+
public function log(){
|
371 |
+
|
372 |
+
$id = $this->input->get('id');
|
373 |
+
|
374 |
+
$wp_uploads = wp_upload_dir();
|
375 |
+
|
376 |
+
PMXI_download::csv($wp_uploads['basedir'] . '/wpallimport_logs/' .$id.'.html');
|
377 |
+
|
378 |
+
}
|
379 |
}
|
controllers/admin/settings.php
CHANGED
@@ -46,12 +46,142 @@ class PMXI_Admin_Settings extends PMXI_Controller_Admin {
|
|
46 |
|
47 |
$this->render();
|
48 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
|
50 |
-
|
|
|
|
|
51 |
|
52 |
-
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
}
|
46 |
|
47 |
$this->render();
|
48 |
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* upload.php
|
52 |
+
*
|
53 |
+
* Copyright 2009, Moxiecode Systems AB
|
54 |
+
* Released under GPL License.
|
55 |
+
*
|
56 |
+
* License: http://www.plupload.com/license
|
57 |
+
* Contributing: http://www.plupload.com/contributing
|
58 |
+
*/
|
59 |
+
public function upload(){
|
60 |
+
|
61 |
+
// HTTP headers for no cache etc
|
62 |
+
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
63 |
+
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
|
64 |
+
header("Cache-Control: no-store, no-cache, must-revalidate");
|
65 |
+
header("Cache-Control: post-check=0, pre-check=0", false);
|
66 |
+
header("Pragma: no-cache");
|
67 |
|
68 |
+
// Settings
|
69 |
+
//$targetDir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
|
70 |
+
$uploads = wp_upload_dir();
|
71 |
|
72 |
+
$targetDir = $uploads['path'];
|
73 |
|
74 |
+
$cleanupTargetDir = true; // Remove old files
|
75 |
+
$maxFileAge = 5 * 3600; // Temp file age in seconds
|
76 |
+
|
77 |
+
// 5 minutes execution time
|
78 |
+
@set_time_limit(5 * 60);
|
79 |
+
|
80 |
+
// Uncomment this one to fake upload time
|
81 |
+
// usleep(5000);
|
82 |
+
|
83 |
+
// Get parameters
|
84 |
+
$chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
|
85 |
+
$chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0;
|
86 |
+
$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
|
87 |
+
|
88 |
+
// Clean the fileName for security reasons
|
89 |
+
$fileName = preg_replace('/[^\w\._]+/', '_', $fileName);
|
90 |
+
|
91 |
+
// Make sure the fileName is unique but only if chunking is disabled
|
92 |
+
if ($chunks < 2 && file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName)) {
|
93 |
+
$ext = strrpos($fileName, '.');
|
94 |
+
$fileName_a = substr($fileName, 0, $ext);
|
95 |
+
$fileName_b = substr($fileName, $ext);
|
96 |
+
|
97 |
+
$count = 1;
|
98 |
+
while (file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName_a . '_' . $count . $fileName_b))
|
99 |
+
$count++;
|
100 |
+
|
101 |
+
$fileName = $fileName_a . '_' . $count . $fileName_b;
|
102 |
+
}
|
103 |
+
|
104 |
+
$filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName;
|
105 |
+
|
106 |
+
// Create target dir
|
107 |
+
if (!file_exists($targetDir))
|
108 |
+
@mkdir($targetDir);
|
109 |
+
|
110 |
+
// Remove old temp files
|
111 |
+
if ($cleanupTargetDir && is_dir($targetDir) && ($dir = opendir($targetDir))) {
|
112 |
+
while (($file = readdir($dir)) !== false) {
|
113 |
+
$tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file;
|
114 |
+
|
115 |
+
// Remove temp file if it is older than the max age and is not the current file
|
116 |
+
if (preg_match('/\.part$/', $file) && (filemtime($tmpfilePath) < time() - $maxFileAge) && ($tmpfilePath != "{$filePath}.part")) {
|
117 |
+
@unlink($tmpfilePath);
|
118 |
+
}
|
119 |
+
}
|
120 |
+
|
121 |
+
closedir($dir);
|
122 |
+
} else
|
123 |
+
exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 100, "message" => "Failed to open temp directory."), "id" => "id")));
|
124 |
+
|
125 |
+
|
126 |
+
// Look for the content type header
|
127 |
+
if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
|
128 |
+
$contentType = $_SERVER["HTTP_CONTENT_TYPE"];
|
129 |
+
|
130 |
+
if (isset($_SERVER["CONTENT_TYPE"]))
|
131 |
+
$contentType = $_SERVER["CONTENT_TYPE"];
|
132 |
+
|
133 |
+
// Handle non multipart uploads older WebKit versions didn't support multipart in HTML5
|
134 |
+
if (strpos($contentType, "multipart") !== false) {
|
135 |
+
if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
|
136 |
+
// Open temp file
|
137 |
+
$out = fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab");
|
138 |
+
if ($out) {
|
139 |
+
// Read binary input stream and append it to temp file
|
140 |
+
$in = fopen($_FILES['file']['tmp_name'], "rb");
|
141 |
+
|
142 |
+
if ($in) {
|
143 |
+
while ($buff = fread($in, 4096))
|
144 |
+
fwrite($out, $buff);
|
145 |
+
} else
|
146 |
+
exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 101, "message" => "Failed to open input stream."), "id" => "id")));
|
147 |
+
fclose($in);
|
148 |
+
fclose($out);
|
149 |
+
@unlink($_FILES['file']['tmp_name']);
|
150 |
+
} else
|
151 |
+
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
|
152 |
+
} else
|
153 |
+
exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 103, "message" => "Failed to move uploaded file."), "id" => "id")));
|
154 |
+
} else {
|
155 |
+
// Open temp file
|
156 |
+
$out = fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab");
|
157 |
+
if ($out) {
|
158 |
+
// Read binary input stream and append it to temp file
|
159 |
+
$in = fopen("php://input", "rb");
|
160 |
+
|
161 |
+
if ($in) {
|
162 |
+
while ($buff = fread($in, 4096))
|
163 |
+
fwrite($out, $buff);
|
164 |
+
} else
|
165 |
+
exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 101, "message" => "Failed to open input stream."), "id" => "id")));
|
166 |
+
|
167 |
+
fclose($in);
|
168 |
+
fclose($out);
|
169 |
+
} else
|
170 |
+
exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 102, "message" => "Failed to open output stream."), "id" => "id")));
|
171 |
+
}
|
172 |
+
|
173 |
+
// Check if file has been uploaded
|
174 |
+
if (!$chunks || $chunk == $chunks - 1) {
|
175 |
+
// Strip the temp .part suffix off
|
176 |
+
rename("{$filePath}.part", $filePath); chmod($filePath, 0755);
|
177 |
+
}
|
178 |
+
|
179 |
+
// Return JSON-RPC response
|
180 |
+
exit(json_encode(array("jsonrpc" => "2.0", "result" => null, "id" => "id", "name" => $filePath)));
|
181 |
+
|
182 |
+
}
|
183 |
+
|
184 |
+
public function download(){
|
185 |
+
PMXI_download::csv(PMXI_Plugin::ROOT_DIR.'/logs/'.$_GET['file'].'.txt');
|
186 |
+
}
|
187 |
}
|
controllers/controller/admin.php
CHANGED
@@ -40,25 +40,36 @@ abstract class PMXI_Controller_Admin extends PMXI_Controller {
|
|
40 |
if ( ! is_a($wp_styles, 'WP_Styles'))
|
41 |
$wp_styles = new WP_Styles();
|
42 |
|
43 |
-
wp_enqueue_style('jquery-ui',
|
44 |
-
wp_enqueue_style('jquery-tipsy',
|
45 |
-
wp_enqueue_style('pmxi-admin-style',
|
46 |
-
wp_enqueue_style('pmxi-admin-style-ie',
|
47 |
$wp_styles->add_data('pmxi-admin-style-ie', 'conditional', 'lte IE 7');
|
48 |
|
49 |
$scheme_color = get_user_option('admin_color') and is_file(PMXI_Plugin::ROOT_DIR . '/static/css/admin-colors-' . $scheme_color . '.css') or $scheme_color = 'fresh';
|
50 |
if (is_file(PMXI_Plugin::ROOT_DIR . '/static/css/admin-colors-' . $scheme_color . '.css')) {
|
51 |
-
wp_enqueue_style('pmxi-admin-style-color',
|
52 |
}
|
53 |
|
54 |
-
wp_enqueue_script('jquery-ui-datepicker',
|
55 |
-
wp_enqueue_script('jquery-ui-autocomplete',
|
56 |
-
wp_enqueue_script('jquery-tipsy',
|
57 |
-
wp_enqueue_script('jquery-nestable',
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
|
63 |
/**
|
64 |
* @see Controller::render()
|
40 |
if ( ! is_a($wp_styles, 'WP_Styles'))
|
41 |
$wp_styles = new WP_Styles();
|
42 |
|
43 |
+
wp_enqueue_style('jquery-ui', PMXI_ROOT_URL . '/static/js/jquery/css/redmond/jquery-ui.css');
|
44 |
+
wp_enqueue_style('jquery-tipsy', PMXI_ROOT_URL . '/static/js/jquery/css/smoothness/jquery.tipsy.css');
|
45 |
+
wp_enqueue_style('pmxi-admin-style', PMXI_ROOT_URL . '/static/css/admin.css');
|
46 |
+
wp_enqueue_style('pmxi-admin-style-ie', PMXI_ROOT_URL . '/static/css/admin-ie.css');
|
47 |
$wp_styles->add_data('pmxi-admin-style-ie', 'conditional', 'lte IE 7');
|
48 |
|
49 |
$scheme_color = get_user_option('admin_color') and is_file(PMXI_Plugin::ROOT_DIR . '/static/css/admin-colors-' . $scheme_color . '.css') or $scheme_color = 'fresh';
|
50 |
if (is_file(PMXI_Plugin::ROOT_DIR . '/static/css/admin-colors-' . $scheme_color . '.css')) {
|
51 |
+
wp_enqueue_style('pmxi-admin-style-color', PMXI_ROOT_URL . '/static/css/admin-colors-' . $scheme_color . '.css');
|
52 |
}
|
53 |
|
54 |
+
wp_enqueue_script('jquery-ui-datepicker', PMXI_ROOT_URL . '/static/js/jquery/ui.datepicker.js', 'jquery-ui-core');
|
55 |
+
wp_enqueue_script('jquery-ui-autocomplete', PMXI_ROOT_URL . '/static/js/jquery/ui.autocomplete.js', array('jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-position'));
|
56 |
+
wp_enqueue_script('jquery-tipsy', PMXI_ROOT_URL . '/static/js/jquery/jquery.tipsy.js', 'jquery');
|
57 |
+
wp_enqueue_script('jquery-nestable', PMXI_ROOT_URL . '/static/js/jquery/jquery.mjs.nestedSortable.js', array('jquery', 'jquery-ui-dialog', 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-tabs', 'jquery-ui-progressbar'));
|
58 |
+
wp_enqueue_script('jquery-moment', PMXI_ROOT_URL . '/static/js/jquery/moment.js', 'jquery');
|
59 |
+
|
60 |
+
/* load plupload scripts */
|
61 |
+
wp_deregister_script('swfupload-all');
|
62 |
+
wp_deregister_script('swfupload-handlers');
|
63 |
+
wp_enqueue_script('swfupload-handlers', get_option('siteurl') . "/wp-includes/js/swfupload/handlers.js", array('jquery'), '2201-20100523');
|
64 |
+
|
65 |
+
wp_enqueue_script('jquery-browserplus-min', 'http://bp.yahooapis.com/2.4.21/browserplus-min.js', array('jquery'));
|
66 |
+
wp_enqueue_script('full-plupload', PMXI_ROOT_URL . '/static/js/plupload/plupload.full.js', array('jquery-browserplus-min'));
|
67 |
+
wp_enqueue_script('jquery-plupload', PMXI_ROOT_URL . '/static/js/plupload/wplupload.js', array('full-plupload', 'jquery'));
|
68 |
+
|
69 |
+
wp_enqueue_script('pmxi-script', PMXI_ROOT_URL . '/static/js/pmxi.js', array('jquery'));
|
70 |
+
wp_enqueue_script('pmxi-admin-script', PMXI_ROOT_URL . '/static/js/admin.js', array('jquery', 'jquery-ui-dialog', 'jquery-ui-datepicker', 'jquery-ui-draggable', 'jquery-ui-droppable'));
|
71 |
+
|
72 |
+
}
|
73 |
|
74 |
/**
|
75 |
* @see Controller::render()
|
helpers/get_file_curl.php
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( ! function_exists('get_file_curl')):
|
3 |
+
|
4 |
+
function get_file_curl($url, $fullpath, $to_variable = false) {
|
5 |
+
|
6 |
+
$ch = curl_init($url);
|
7 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
8 |
+
$rawdata = curl_exec_follow($ch);
|
9 |
+
|
10 |
+
$result = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
11 |
+
|
12 |
+
curl_close ($ch);
|
13 |
+
|
14 |
+
if(file_exists($fullpath)) unlink($fullpath);
|
15 |
+
|
16 |
+
$fp = fopen($fullpath,'w');
|
17 |
+
fwrite($fp, $rawdata);
|
18 |
+
fclose($fp);
|
19 |
+
|
20 |
+
return ($result == 200) ? (($to_variable) ? $rawdata : true) : false;
|
21 |
+
}
|
22 |
+
|
23 |
+
endif;
|
24 |
+
|
25 |
+
if (!function_exists('curl_exec_follow')):
|
26 |
+
function curl_exec_follow($ch, &$maxredirect = null) {
|
27 |
+
|
28 |
+
$mr = $maxredirect === null ? 5 : intval($maxredirect);
|
29 |
+
|
30 |
+
if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) {
|
31 |
+
|
32 |
+
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $mr > 0);
|
33 |
+
curl_setopt($ch, CURLOPT_MAXREDIRS, $mr);
|
34 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
35 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
36 |
+
|
37 |
+
} else {
|
38 |
+
|
39 |
+
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
|
40 |
+
|
41 |
+
if ($mr > 0)
|
42 |
+
{
|
43 |
+
$original_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
|
44 |
+
$newurl = $original_url;
|
45 |
+
|
46 |
+
$rch = curl_copy_handle($ch);
|
47 |
+
|
48 |
+
curl_setopt($rch, CURLOPT_HEADER, true);
|
49 |
+
curl_setopt($rch, CURLOPT_NOBODY, true);
|
50 |
+
curl_setopt($rch, CURLOPT_FORBID_REUSE, false);
|
51 |
+
do
|
52 |
+
{
|
53 |
+
curl_setopt($rch, CURLOPT_URL, $newurl);
|
54 |
+
$header = curl_exec($rch);
|
55 |
+
if (curl_errno($rch)) {
|
56 |
+
$code = 0;
|
57 |
+
} else {
|
58 |
+
$code = curl_getinfo($rch, CURLINFO_HTTP_CODE);
|
59 |
+
if ($code == 301 || $code == 302) {
|
60 |
+
preg_match('/Location:(.*?)\n/', $header, $matches);
|
61 |
+
$newurl = trim(array_pop($matches));
|
62 |
+
|
63 |
+
// if no scheme is present then the new url is a
|
64 |
+
// relative path and thus needs some extra care
|
65 |
+
if(!preg_match("/^https?:/i", $newurl)){
|
66 |
+
$newurl = $original_url . $newurl;
|
67 |
+
}
|
68 |
+
} else {
|
69 |
+
$code = 0;
|
70 |
+
}
|
71 |
+
}
|
72 |
+
} while ($code && --$mr);
|
73 |
+
|
74 |
+
curl_close($rch);
|
75 |
+
|
76 |
+
if (!$mr)
|
77 |
+
{
|
78 |
+
if ($maxredirect === null)
|
79 |
+
trigger_error('Too many redirects.', E_USER_WARNING);
|
80 |
+
else
|
81 |
+
$maxredirect = 0;
|
82 |
+
|
83 |
+
return false;
|
84 |
+
}
|
85 |
+
curl_setopt($ch, CURLOPT_URL, $newurl);
|
86 |
+
}
|
87 |
+
}
|
88 |
+
return curl_exec($ch);
|
89 |
+
}
|
90 |
+
endif;
|
helpers/import_custom_meta_box.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if (!function_exists('import_custom_meta_box')){
|
3 |
+
function import_custom_meta_box($edit_post) {
|
4 |
+
?>
|
5 |
+
<div id="postcustomstuff">
|
6 |
+
<table id="list-table">
|
7 |
+
<tbody class="list:meta" id="the-list">
|
8 |
+
<?php if (!empty($_SESSION['pmxi_import']['options']['custom_name'])): foreach ($_SESSION['pmxi_import']['options']['custom_name'] as $i => $name): ?>
|
9 |
+
<tr>
|
10 |
+
<td class="left">
|
11 |
+
<label class="screen-reader-text">Key</label>
|
12 |
+
<input type="text" value="<?php echo esc_attr($name) ?>" name="custom_name[]" size="20">
|
13 |
+
<div class="submit"><input type="submit" class="delete deletemeta" value="Delete"></div>
|
14 |
+
</td>
|
15 |
+
<td>
|
16 |
+
<label class="screen-reader-text">Value</label>
|
17 |
+
<textarea name="custom_value[]" rows="2" cols="30" class="widefat"><?php echo esc_html($_SESSION['pmxi_import']['options']['custom_value'][$i]) ?></textarea>
|
18 |
+
</td>
|
19 |
+
</tr>
|
20 |
+
<?php endforeach; endif; ?>
|
21 |
+
</tbody>
|
22 |
+
</table>
|
23 |
+
<?php meta_form(); ?>
|
24 |
+
</div>
|
25 |
+
<p><?php _e('Custom fields can be used to add extra metadata to a post that you can <a href="http://codex.wordpress.org/Using_Custom_Fields" target="_blank">use in your theme</a>.'); ?></p>
|
26 |
+
<?php
|
27 |
+
}
|
28 |
+
}
|
29 |
+
?>
|
helpers/pmxi_functions.php
ADDED
@@ -0,0 +1,285 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* IF statement
|
4 |
+
*
|
5 |
+
* @access public
|
6 |
+
* @param string
|
7 |
+
* @param string
|
8 |
+
* @param string
|
9 |
+
* @param string
|
10 |
+
* @param string
|
11 |
+
* @return string
|
12 |
+
*/
|
13 |
+
if (!function_exists('pmxi_if')){
|
14 |
+
function pmxi_if($left_condition, $operand = '', $right_condition = '', $then, $else = ''){
|
15 |
+
$str = trim(implode(' ', array($left_condition, html_entity_decode($operand), $right_condition)));
|
16 |
+
return (eval ("return ($str);")) ? $then : $else;
|
17 |
+
}
|
18 |
+
}
|
19 |
+
|
20 |
+
function is_empty($var)
|
21 |
+
{
|
22 |
+
return empty($var);
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Word Limiter
|
28 |
+
*
|
29 |
+
* Limits a string to X number of words.
|
30 |
+
*
|
31 |
+
* @access public
|
32 |
+
* @param string
|
33 |
+
* @param string
|
34 |
+
* @param string the end character. Usually an ellipsis
|
35 |
+
* @return string
|
36 |
+
*/
|
37 |
+
if ( ! function_exists('pmxi_word_limiter'))
|
38 |
+
{
|
39 |
+
function pmxi_word_limiter($str, $limit = 100, $end_char = '…')
|
40 |
+
{
|
41 |
+
if (trim($str) == '')
|
42 |
+
{
|
43 |
+
return $str;
|
44 |
+
}
|
45 |
+
|
46 |
+
preg_match('/^\s*+(?:\S++\s*+){1,'.(int) $limit.'}/', $str, $matches);
|
47 |
+
|
48 |
+
if (strlen($str) == strlen($matches[0]))
|
49 |
+
{
|
50 |
+
$end_char = '';
|
51 |
+
}
|
52 |
+
|
53 |
+
return rtrim($matches[0]).$end_char;
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Character Limiter
|
59 |
+
*
|
60 |
+
* Limits the string based on the character count. Preserves complete words
|
61 |
+
* so the character count may not be exactly as specified.
|
62 |
+
*
|
63 |
+
* @access public
|
64 |
+
* @param string
|
65 |
+
* @param string
|
66 |
+
* @param string the end character. Usually an ellipsis
|
67 |
+
* @return string
|
68 |
+
*/
|
69 |
+
if ( ! function_exists('pmxi_character_limiter'))
|
70 |
+
{
|
71 |
+
function pmxi_character_limiter($str, $n = 500, $end_char = '…')
|
72 |
+
{
|
73 |
+
if (strlen($str) < $n)
|
74 |
+
{
|
75 |
+
return $str;
|
76 |
+
}
|
77 |
+
|
78 |
+
$str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
|
79 |
+
|
80 |
+
if (strlen($str) <= $n)
|
81 |
+
{
|
82 |
+
return $str;
|
83 |
+
}
|
84 |
+
|
85 |
+
$out = "";
|
86 |
+
foreach (explode(' ', trim($str)) as $val)
|
87 |
+
{
|
88 |
+
$out .= $val.' ';
|
89 |
+
|
90 |
+
if (strlen($out) >= $n)
|
91 |
+
{
|
92 |
+
$out = trim($out);
|
93 |
+
return (strlen($out) == strlen($str)) ? $out : $out.$end_char;
|
94 |
+
}
|
95 |
+
}
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
function url_title($str, $separator = 'dash', $lowercase = FALSE)
|
100 |
+
{
|
101 |
+
if ($separator == 'dash')
|
102 |
+
{
|
103 |
+
$search = '_';
|
104 |
+
$replace = '-';
|
105 |
+
}
|
106 |
+
else
|
107 |
+
{
|
108 |
+
$search = '-';
|
109 |
+
$replace = '_';
|
110 |
+
}
|
111 |
+
|
112 |
+
$trans = array(
|
113 |
+
'&\#\d+?;' => '',
|
114 |
+
'&\S+?;' => '',
|
115 |
+
'\s+' => $replace,
|
116 |
+
'[^a-z0-9\-\._]' => '',
|
117 |
+
$replace.'+' => $replace,
|
118 |
+
$replace.'$' => $replace,
|
119 |
+
'^'.$replace => $replace,
|
120 |
+
'\.+$' => ''
|
121 |
+
);
|
122 |
+
|
123 |
+
$str = strip_tags($str);
|
124 |
+
|
125 |
+
foreach ($trans as $key => $val)
|
126 |
+
{
|
127 |
+
$str = preg_replace("#".$key."#i", $val, $str);
|
128 |
+
}
|
129 |
+
|
130 |
+
if ($lowercase === TRUE)
|
131 |
+
{
|
132 |
+
$str = strtolower($str);
|
133 |
+
}
|
134 |
+
|
135 |
+
return trim(stripslashes($str));
|
136 |
+
}
|
137 |
+
|
138 |
+
|
139 |
+
function rand_char($length) {
|
140 |
+
$random = '';
|
141 |
+
for ($i = 0; $i < $length; $i++) {
|
142 |
+
$random .= chr(mt_rand(33, 126));
|
143 |
+
}
|
144 |
+
return $random;
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Reading large files from remote server
|
149 |
+
* @ $filePath - file URL
|
150 |
+
* return local path of copied file
|
151 |
+
*/
|
152 |
+
function pmxi_copy_url_file($filePath, $detect = false){
|
153 |
+
/*$ctx = stream_context_create();
|
154 |
+
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));*/
|
155 |
+
|
156 |
+
$type = (preg_match('%\W(csv)$%i', basename($filePath))) ? 'csv' : false;
|
157 |
+
$type = (preg_match('%\W(xml)$%i', basename($filePath))) ? 'xml' : false;
|
158 |
+
|
159 |
+
$uploads = wp_upload_dir();
|
160 |
+
$tmpname = wp_unique_filename($uploads['path'], basename($filePath));
|
161 |
+
$localPath = $uploads['path'] .'/'. $tmpname;
|
162 |
+
|
163 |
+
get_file_curl($filePath, $localPath);
|
164 |
+
|
165 |
+
if (file_exists($localPath)) {
|
166 |
+
|
167 |
+
if (!$type){
|
168 |
+
$file = @fopen($localPath, "rb");
|
169 |
+
while (!feof($file)) {
|
170 |
+
$chunk = @fread($file, 1024);
|
171 |
+
if (strpos($chunk, "<") !== false) $type = 'xml'; else $type = 'csv'; // if it's a 1st chunk, then chunk <? symbols to detect XML file
|
172 |
+
break;
|
173 |
+
}
|
174 |
+
@fclose($file);
|
175 |
+
}
|
176 |
+
|
177 |
+
} else {
|
178 |
+
$file = @fopen($filePath, "rb");
|
179 |
+
$fp = @fopen($localPath, 'w');
|
180 |
+
$first_chunk = true;
|
181 |
+
while (!feof($file)) {
|
182 |
+
$chunk = @fread($file, 1024);
|
183 |
+
if (!$type and $first_chunk and strpos($chunk, "<") !== false) $type = 'xml'; elseif (!$type and $first_chunk) $type = 'csv'; // if it's a 1st chunk, then chunk <? symbols to detect XML file
|
184 |
+
$first_chunk = false;
|
185 |
+
@fwrite($fp, $chunk);
|
186 |
+
}
|
187 |
+
@fclose($file);
|
188 |
+
@fclose($fp);
|
189 |
+
}
|
190 |
+
|
191 |
+
return ($detect) ? array('type' => $type, 'localPath' => $localPath) : $localPath;
|
192 |
+
}
|
193 |
+
|
194 |
+
function pmxi_gzfile_get_contents($filename, $use_include_path = 0) {
|
195 |
+
|
196 |
+
$type = 'csv';
|
197 |
+
$uploads = wp_upload_dir();
|
198 |
+
$tmpname = wp_unique_filename($uploads['path'], basename($filename));
|
199 |
+
$fp = @fopen($uploads['path'] .'/'. $tmpname, 'w');
|
200 |
+
|
201 |
+
$file = @gzopen($filename, 'rb', $use_include_path);
|
202 |
+
if ($file) {
|
203 |
+
$first_chunk = true;
|
204 |
+
while (!gzeof($file)) {
|
205 |
+
$chunk = gzread($file, 1024);
|
206 |
+
if ($first_chunk and strpos($chunk, "<") !== false) { $type = 'xml'; $first_chunk = false; } // if it's a 1st chunk, then chunk <? symbols to detect XML file
|
207 |
+
@fwrite($fp, $chunk);
|
208 |
+
}
|
209 |
+
gzclose($file);
|
210 |
+
}
|
211 |
+
@fclose($fp);
|
212 |
+
$localPath = $uploads['path'] .'/'. $tmpname;
|
213 |
+
return array('type' => $type, 'localPath' => $localPath);
|
214 |
+
}
|
215 |
+
|
216 |
+
function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) {
|
217 |
+
static $filesize = null;
|
218 |
+
|
219 |
+
$msg = '';
|
220 |
+
switch($notification_code) {
|
221 |
+
case STREAM_NOTIFY_RESOLVE:
|
222 |
+
case STREAM_NOTIFY_AUTH_REQUIRED:
|
223 |
+
case STREAM_NOTIFY_COMPLETED:
|
224 |
+
case STREAM_NOTIFY_FAILURE:
|
225 |
+
case STREAM_NOTIFY_AUTH_RESULT:
|
226 |
+
/* Ignore */
|
227 |
+
break;
|
228 |
+
|
229 |
+
case STREAM_NOTIFY_REDIRECTED:
|
230 |
+
//$msg = "Being redirected to: ". $message;
|
231 |
+
break;
|
232 |
+
|
233 |
+
case STREAM_NOTIFY_CONNECT:
|
234 |
+
//$msg = "Connected...";
|
235 |
+
break;
|
236 |
+
|
237 |
+
case STREAM_NOTIFY_FILE_SIZE_IS:
|
238 |
+
$filesize = $bytes_max;
|
239 |
+
//$msg = "Filesize: ". $filesize;
|
240 |
+
break;
|
241 |
+
|
242 |
+
case STREAM_NOTIFY_MIME_TYPE_IS:
|
243 |
+
//$msg = "Mime-type: ". $message;
|
244 |
+
break;
|
245 |
+
|
246 |
+
case STREAM_NOTIFY_PROGRESS:
|
247 |
+
if ($bytes_transferred > 0) {
|
248 |
+
echo "<script type='text/javascript'>";
|
249 |
+
if (!isset($filesize)) {
|
250 |
+
printf("document.getElementById('url_progressbar').innerHTML('Unknown filesize.. %2d kb done..');", $bytes_transferred/1024);
|
251 |
+
} else {
|
252 |
+
$length = (int)(($bytes_transferred/$filesize)*100);
|
253 |
+
echo "document.getElementById('url_upload_value').style.width = ".$length."%";
|
254 |
+
printf("document.getElementById('url_progressbar').innerHTML('%02d%% (%0".strlen($filesize/1024)."d/%2d kb)');", $length, ($bytes_transferred/1024), $filesize/1024);
|
255 |
+
}
|
256 |
+
echo "</script>";
|
257 |
+
echo(str_repeat(' ', 256));
|
258 |
+
if (@ob_get_contents()) {
|
259 |
+
@ob_end_flush();
|
260 |
+
}
|
261 |
+
flush();
|
262 |
+
}
|
263 |
+
break;
|
264 |
+
}
|
265 |
+
}
|
266 |
+
|
267 |
+
function pmxi_strip_tags_content($text, $tags = '', $invert = FALSE) {
|
268 |
+
|
269 |
+
preg_match_all('/<(.+?)[\s]*\/?[\s]*>/si', trim($tags), $tags);
|
270 |
+
$tags = array_unique($tags[1]);
|
271 |
+
|
272 |
+
if(is_array($tags) AND count($tags) > 0) {
|
273 |
+
if($invert == FALSE) {
|
274 |
+
return preg_replace('@<(?!(?:'. implode('|', $tags) .')\b)(\w+)\b.*?>.*?</\1>@si', '', $text);
|
275 |
+
}
|
276 |
+
else {
|
277 |
+
return preg_replace('@<('. implode('|', $tags) .')\b.*?>.*?</\1>@si', '', $text);
|
278 |
+
}
|
279 |
+
}
|
280 |
+
elseif($invert == FALSE) {
|
281 |
+
return preg_replace('@<(\w+)\b.*?>.*?</\1>@si', '', $text);
|
282 |
+
}
|
283 |
+
return $text;
|
284 |
+
}
|
285 |
+
|
libraries/XmlImportCsvParse.php
CHANGED
@@ -71,7 +71,15 @@ class PMXI_CsvParser
|
|
71 |
'eol' => '',
|
72 |
'length' => 999999,
|
73 |
'escape' => '"'
|
74 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
|
76 |
protected
|
77 |
|
@@ -108,11 +116,14 @@ class PMXI_CsvParser
|
|
108 |
* @see load()
|
109 |
* @return void
|
110 |
*/
|
111 |
-
public function __construct($filename = null)
|
112 |
{
|
|
|
|
|
|
|
113 |
|
114 |
ini_set( "display_errors", 0);
|
115 |
-
|
116 |
|
117 |
$file_params = self::analyse_file($filename, 10);
|
118 |
|
@@ -128,36 +139,6 @@ class PMXI_CsvParser
|
|
128 |
*
|
129 |
* indicates the object which file is to be loaded
|
130 |
*
|
131 |
-
* <code>
|
132 |
-
*
|
133 |
-
* require_once 'File/CSV/DataSource.php';
|
134 |
-
*
|
135 |
-
* $csv = new File_CSV_DataSource;
|
136 |
-
* $csv->load('my_cool.csv');
|
137 |
-
* var_export($csv->connect());
|
138 |
-
*
|
139 |
-
* array (
|
140 |
-
* 0 =>
|
141 |
-
* array (
|
142 |
-
* 'name' => 'john',
|
143 |
-
* 'age' => '13',
|
144 |
-
* 'skill' => 'knows magic',
|
145 |
-
* ),
|
146 |
-
* 1 =>
|
147 |
-
* array (
|
148 |
-
* 'name' => 'tanaka',
|
149 |
-
* 'age' => '8',
|
150 |
-
* 'skill' => 'makes sushi',
|
151 |
-
* ),
|
152 |
-
* 2 =>
|
153 |
-
* array (
|
154 |
-
* 'name' => 'jose',
|
155 |
-
* 'age' => '5',
|
156 |
-
* 'skill' => 'dances salsa',
|
157 |
-
* ),
|
158 |
-
* )
|
159 |
-
*
|
160 |
-
* </code>
|
161 |
*
|
162 |
* @param string $filename the csv filename to load
|
163 |
*
|
@@ -177,16 +158,6 @@ class PMXI_CsvParser
|
|
177 |
*
|
178 |
* lets you define different settings for scanning
|
179 |
*
|
180 |
-
* Given array will override the internal settings
|
181 |
-
*
|
182 |
-
* <code>
|
183 |
-
* $settings = array(
|
184 |
-
* 'delimiter' => ',',
|
185 |
-
* 'eol' => ";",
|
186 |
-
* 'length' => 999999,
|
187 |
-
* 'escape' => '"'
|
188 |
-
* );
|
189 |
-
* </code>
|
190 |
*
|
191 |
* @param mixed $array containing settings to use
|
192 |
*
|
@@ -204,18 +175,6 @@ class PMXI_CsvParser
|
|
204 |
*
|
205 |
* gets csv headers into an array
|
206 |
*
|
207 |
-
* <code>
|
208 |
-
*
|
209 |
-
* var_export($csv->getHeaders());
|
210 |
-
*
|
211 |
-
* array (
|
212 |
-
* 0 => 'name',
|
213 |
-
* 1 => 'age',
|
214 |
-
* 2 => 'skill',
|
215 |
-
* )
|
216 |
-
*
|
217 |
-
* </code>
|
218 |
-
*
|
219 |
* @access public
|
220 |
* @return array
|
221 |
*/
|
@@ -242,78 +201,7 @@ class PMXI_CsvParser
|
|
242 |
*
|
243 |
* Attempts to create a relationship for every single cell that
|
244 |
* was captured and its corresponding header. The sample below shows
|
245 |
-
* how a connection/relationship is built.
|
246 |
-
*
|
247 |
-
* sample of a csv file "my_cool.csv"
|
248 |
-
*
|
249 |
-
* <code>
|
250 |
-
* name,age,skill
|
251 |
-
* john,13,knows magic
|
252 |
-
* tanaka,8,makes sushi
|
253 |
-
* jose,5,dances salsa
|
254 |
-
* </code>
|
255 |
-
*
|
256 |
-
* php implementation
|
257 |
-
*
|
258 |
-
* <code>
|
259 |
-
*
|
260 |
-
* $csv = new File_CSV_DataSource;
|
261 |
-
* $csv->load('my_cool.csv');
|
262 |
-
*
|
263 |
-
* if (!$csv->isSymmetric()) {
|
264 |
-
* die('file has headers and rows with different lengths
|
265 |
-
* cannot connect');
|
266 |
-
* }
|
267 |
-
*
|
268 |
-
* var_export($csv->connect());
|
269 |
-
*
|
270 |
-
* array (
|
271 |
-
* 0 =>
|
272 |
-
* array (
|
273 |
-
* 'name' => 'john',
|
274 |
-
* 'age' => '13',
|
275 |
-
* 'skill' => 'knows magic',
|
276 |
-
* ),
|
277 |
-
* 1 =>
|
278 |
-
* array (
|
279 |
-
* 'name' => 'tanaka',
|
280 |
-
* 'age' => '8',
|
281 |
-
* 'skill' => 'makes sushi',
|
282 |
-
* ),
|
283 |
-
* 2 =>
|
284 |
-
* array (
|
285 |
-
* 'name' => 'jose',
|
286 |
-
* 'age' => '5',
|
287 |
-
* 'skill' => 'dances salsa',
|
288 |
-
* ),
|
289 |
-
* )
|
290 |
-
*
|
291 |
-
* </code>
|
292 |
-
*
|
293 |
-
*
|
294 |
-
* You can pass a collection of headers in an array to build
|
295 |
-
* a connection for those columns only!
|
296 |
-
*
|
297 |
-
* <code>
|
298 |
-
*
|
299 |
-
* var_export($csv->connect(array('age')));
|
300 |
-
*
|
301 |
-
* array (
|
302 |
-
* 0 =>
|
303 |
-
* array (
|
304 |
-
* 'age' => '13',
|
305 |
-
* ),
|
306 |
-
* 1 =>
|
307 |
-
* array (
|
308 |
-
* 'age' => '8',
|
309 |
-
* ),
|
310 |
-
* 2 =>
|
311 |
-
* array (
|
312 |
-
* 'age' => '5',
|
313 |
-
* ),
|
314 |
-
* )
|
315 |
-
*
|
316 |
-
* </code>
|
317 |
*
|
318 |
* @param array $columns the columns to connect, if nothing
|
319 |
* is given all headers will be used to create a connection
|
@@ -385,35 +273,6 @@ class PMXI_CsvParser
|
|
385 |
* lets assume that we add one more row to our csv file.
|
386 |
* that has only two values. Something like
|
387 |
*
|
388 |
-
* <code>
|
389 |
-
* name,age,skill
|
390 |
-
* john,13,knows magic
|
391 |
-
* tanaka,8,makes sushi
|
392 |
-
* jose,5,dances salsa
|
393 |
-
* niki,6
|
394 |
-
* </code>
|
395 |
-
*
|
396 |
-
* Then in our php code
|
397 |
-
*
|
398 |
-
* <code>
|
399 |
-
* $csv->load('my_cool.csv');
|
400 |
-
* var_export($csv->getAsymmetricRows());
|
401 |
-
* </code>
|
402 |
-
*
|
403 |
-
* The result
|
404 |
-
*
|
405 |
-
* <code>
|
406 |
-
*
|
407 |
-
* array (
|
408 |
-
* 0 =>
|
409 |
-
* array (
|
410 |
-
* 0 => 'niki',
|
411 |
-
* 1 => '6',
|
412 |
-
* ),
|
413 |
-
* )
|
414 |
-
*
|
415 |
-
* </code>
|
416 |
-
*
|
417 |
* @access public
|
418 |
* @return array filled with rows that do not match headers
|
419 |
* @see getHeaders(), symmetrize(), isSymmetric(),
|
@@ -500,35 +359,6 @@ class PMXI_CsvParser
|
|
500 |
*
|
501 |
* Note $name is the same as the items returned by getHeaders()
|
502 |
*
|
503 |
-
* sample of a csv file "my_cool.csv"
|
504 |
-
*
|
505 |
-
* <code>
|
506 |
-
* name,age,skill
|
507 |
-
* john,13,knows magic
|
508 |
-
* tanaka,8,makes sushi
|
509 |
-
* jose,5,dances salsa
|
510 |
-
* </code>
|
511 |
-
*
|
512 |
-
* php implementation
|
513 |
-
*
|
514 |
-
* <code>
|
515 |
-
* $csv = new File_CSV_DataSource;
|
516 |
-
* $csv->load('my_cool.csv');
|
517 |
-
* var_export($csv->getColumn('name'));
|
518 |
-
* </code>
|
519 |
-
*
|
520 |
-
* the above example outputs something like
|
521 |
-
*
|
522 |
-
* <code>
|
523 |
-
*
|
524 |
-
* array (
|
525 |
-
* 0 => 'john',
|
526 |
-
* 1 => 'tanaka',
|
527 |
-
* 2 => 'jose',
|
528 |
-
* )
|
529 |
-
*
|
530 |
-
* </code>
|
531 |
-
*
|
532 |
* @param string $name the name of the column to fetch
|
533 |
*
|
534 |
* @access public
|
@@ -555,31 +385,6 @@ class PMXI_CsvParser
|
|
555 |
* checks if a column exists, columns are identified by their
|
556 |
* header name.
|
557 |
*
|
558 |
-
* sample of a csv file "my_cool.csv"
|
559 |
-
*
|
560 |
-
* <code>
|
561 |
-
* name,age,skill
|
562 |
-
* john,13,knows magic
|
563 |
-
* tanaka,8,makes sushi
|
564 |
-
* jose,5,dances salsa
|
565 |
-
* </code>
|
566 |
-
*
|
567 |
-
* php implementation
|
568 |
-
*
|
569 |
-
* <code>
|
570 |
-
* $csv = new File_CSV_DataSource;
|
571 |
-
* $csv->load('my_cool.csv');
|
572 |
-
* $headers = $csv->getHeaders();
|
573 |
-
* </code>
|
574 |
-
*
|
575 |
-
* now lets check if the columns exist
|
576 |
-
*
|
577 |
-
* <code>
|
578 |
-
* var_export($csv->hasColumn($headers[0])); // true
|
579 |
-
* var_export($csv->hasColumn('age')); // true
|
580 |
-
* var_export($csv->hasColumn('I dont exist')); // false
|
581 |
-
* </code>
|
582 |
-
*
|
583 |
* @param string $string an item returned by getHeaders()
|
584 |
*
|
585 |
* @access public
|
@@ -595,49 +400,6 @@ class PMXI_CsvParser
|
|
595 |
* column appender
|
596 |
*
|
597 |
* Appends a column and each or all values in it can be
|
598 |
-
* dinamically filled. Only when the $values argument is given.
|
599 |
-
* <code>
|
600 |
-
*
|
601 |
-
*
|
602 |
-
* var_export($csv->fillColumn('age', 99));
|
603 |
-
* true
|
604 |
-
*
|
605 |
-
* var_export($csv->appendColumn('candy_ownership', array(99, 44, 65)));
|
606 |
-
* true
|
607 |
-
*
|
608 |
-
* var_export($csv->appendColumn('import_id', 111111111));
|
609 |
-
* true
|
610 |
-
*
|
611 |
-
* var_export($csv->connect());
|
612 |
-
*
|
613 |
-
* array (
|
614 |
-
* 0 =>
|
615 |
-
* array (
|
616 |
-
* 'name' => 'john',
|
617 |
-
* 'age' => 99,
|
618 |
-
* 'skill' => 'knows magic',
|
619 |
-
* 'candy_ownership' => 99,
|
620 |
-
* 'import_id' => 111111111,
|
621 |
-
* ),
|
622 |
-
* 1 =>
|
623 |
-
* array (
|
624 |
-
* 'name' => 'tanaka',
|
625 |
-
* 'age' => 99,
|
626 |
-
* 'skill' => 'makes sushi',
|
627 |
-
* 'candy_ownership' => 44,
|
628 |
-
* 'import_id' => 111111111,
|
629 |
-
* ),
|
630 |
-
* 2 =>
|
631 |
-
* array (
|
632 |
-
* 'name' => 'jose',
|
633 |
-
* 'age' => 99,
|
634 |
-
* 'skill' => 'dances salsa',
|
635 |
-
* 'candy_ownership' => 65,
|
636 |
-
* 'import_id' => 111111111,
|
637 |
-
* ),
|
638 |
-
* )
|
639 |
-
*
|
640 |
-
* </code>
|
641 |
*
|
642 |
* @param string $column an item returned by getHeaders()
|
643 |
* @param mixed $values same as fillColumn()
|
@@ -674,71 +436,6 @@ class PMXI_CsvParser
|
|
674 |
*
|
675 |
* fills alll the data in the given column with $values
|
676 |
*
|
677 |
-
* sample of a csv file "my_cool.csv"
|
678 |
-
*
|
679 |
-
* <code>
|
680 |
-
* name,age,skill
|
681 |
-
* john,13,knows magic
|
682 |
-
* tanaka,8,makes sushi
|
683 |
-
* jose,5,dances salsa
|
684 |
-
* </code>
|
685 |
-
*
|
686 |
-
* php implementation
|
687 |
-
*
|
688 |
-
* <code>
|
689 |
-
* $csv = new File_CSV_DataSource;
|
690 |
-
* $csv->load('my_cool.csv');
|
691 |
-
*
|
692 |
-
* // if the csv file loads
|
693 |
-
* if ($csv->load('my_cool.csv')) {
|
694 |
-
*
|
695 |
-
* // grab all data within the age column
|
696 |
-
* var_export($csv->getColumn('age'));
|
697 |
-
*
|
698 |
-
* // rename all values in it with the number 99
|
699 |
-
* var_export($csv->fillColumn('age', 99));
|
700 |
-
*
|
701 |
-
* // grab all data within the age column
|
702 |
-
* var_export($csv->getColumn('age'));
|
703 |
-
*
|
704 |
-
* // rename each value in a column independently
|
705 |
-
* $data = array(1, 2, 3);
|
706 |
-
* $csv->fillColumn('age', $data);
|
707 |
-
*
|
708 |
-
* var_export($csv->getColumn('age'));
|
709 |
-
* }
|
710 |
-
* </code>
|
711 |
-
*
|
712 |
-
* standard output
|
713 |
-
*
|
714 |
-
* <code>
|
715 |
-
* array (
|
716 |
-
* 0 => '13',
|
717 |
-
* 1 => '8',
|
718 |
-
* 2 => '5',
|
719 |
-
* )
|
720 |
-
* </code>
|
721 |
-
*
|
722 |
-
* <code>
|
723 |
-
* true
|
724 |
-
* </code>
|
725 |
-
*
|
726 |
-
* <code>
|
727 |
-
* array (
|
728 |
-
* 0 => 99,
|
729 |
-
* 1 => 99,
|
730 |
-
* 2 => 99,
|
731 |
-
* )
|
732 |
-
* </code>
|
733 |
-
*
|
734 |
-
* <code>
|
735 |
-
* array (
|
736 |
-
* 0 => 1,
|
737 |
-
* 1 => 2,
|
738 |
-
* 2 => 3,
|
739 |
-
* )
|
740 |
-
* </code>
|
741 |
-
*
|
742 |
* @param mixed $column the column identified by a string
|
743 |
* @param mixed $values ither one of the following
|
744 |
* - (Number) will fill the whole column with the value of number
|
@@ -790,89 +487,7 @@ class PMXI_CsvParser
|
|
790 |
/**
|
791 |
* column remover
|
792 |
*
|
793 |
-
* Completly removes a whole column identified by $name
|
794 |
-
* Note: that this function will only work if data is symmetric.
|
795 |
-
*
|
796 |
-
* sample of a csv file "my_cool.csv"
|
797 |
-
*
|
798 |
-
* <code>
|
799 |
-
* name,age,skill
|
800 |
-
* john,13,knows magic
|
801 |
-
* tanaka,8,makes sushi
|
802 |
-
* jose,5,dances salsa
|
803 |
-
* </code>
|
804 |
-
*
|
805 |
-
* load the library and csv file
|
806 |
-
*
|
807 |
-
* <code>
|
808 |
-
* require_once 'File/CSV/DataSource.php';
|
809 |
-
* $csv = new File_CSV_DataSource;
|
810 |
-
* $csv->load('my_cool.csv');
|
811 |
-
* </code>
|
812 |
-
*
|
813 |
-
* lets dump currently loaded data
|
814 |
-
* <code>
|
815 |
-
* var_export($csv->connect());
|
816 |
-
* </code>
|
817 |
-
*
|
818 |
-
* output
|
819 |
-
*
|
820 |
-
* <code>
|
821 |
-
* array (
|
822 |
-
* 0 =>
|
823 |
-
* array (
|
824 |
-
* 'name' => 'john',
|
825 |
-
* 'age' => '13',
|
826 |
-
* 'skill' => 'knows magic',
|
827 |
-
* ),
|
828 |
-
* 1 =>
|
829 |
-
* array (
|
830 |
-
* 'name' => 'tanaka',
|
831 |
-
* 'age' => '8',
|
832 |
-
* 'skill' => 'makes sushi',
|
833 |
-
* ),
|
834 |
-
* 2 =>
|
835 |
-
* array (
|
836 |
-
* 'name' => 'jose',
|
837 |
-
* 'age' => '5',
|
838 |
-
* 'skill' => 'dances salsa',
|
839 |
-
* ),
|
840 |
-
* )
|
841 |
-
* </code>
|
842 |
-
*
|
843 |
-
* and now let's remove the second column
|
844 |
-
*
|
845 |
-
* <code>
|
846 |
-
* var_export($csv->removeColumn('age'));
|
847 |
-
* </code>
|
848 |
-
*
|
849 |
-
* output
|
850 |
-
*
|
851 |
-
* <code>
|
852 |
-
* true
|
853 |
-
* </code>
|
854 |
-
*
|
855 |
-
* those changes made let's dump the data again and see what we got
|
856 |
-
*
|
857 |
-
* <code>
|
858 |
-
* array (
|
859 |
-
* 0 =>
|
860 |
-
* array (
|
861 |
-
* 'name' => 'john',
|
862 |
-
* 'skill' => 'knows magic',
|
863 |
-
* ),
|
864 |
-
* 1 =>
|
865 |
-
* array (
|
866 |
-
* 'name' => 'tanaka',
|
867 |
-
* 'skill' => 'makes sushi',
|
868 |
-
* ),
|
869 |
-
* 2 =>
|
870 |
-
* array (
|
871 |
-
* 'name' => 'jose',
|
872 |
-
* 'skill' => 'dances salsa',
|
873 |
-
* ),
|
874 |
-
* )
|
875 |
-
* </code>
|
876 |
*
|
877 |
* @param string $name same as the ones returned by getHeaders();
|
878 |
*
|
@@ -945,30 +560,7 @@ class PMXI_CsvParser
|
|
945 |
/**
|
946 |
* cell fetcher
|
947 |
*
|
948 |
-
* gets the value of a specific cell by given coordinates
|
949 |
-
*
|
950 |
-
* Note: That indexes start with zero, and headers are not
|
951 |
-
* searched!
|
952 |
-
*
|
953 |
-
* For example if we are trying to grab the cell that is in the
|
954 |
-
* second row and the third column
|
955 |
-
*
|
956 |
-
* <code>
|
957 |
-
* name,age,skill
|
958 |
-
* john,13,knows magic
|
959 |
-
* tanaka,8,makes sushi
|
960 |
-
* jose,5,dances salsa
|
961 |
-
* </code>
|
962 |
-
*
|
963 |
-
* we would do something like
|
964 |
-
* <code>
|
965 |
-
* var_export($csv->getCell(1, 2));
|
966 |
-
* </code>
|
967 |
-
*
|
968 |
-
* and get the following results
|
969 |
-
* <code>
|
970 |
-
* 'makes sushi'
|
971 |
-
* </code>
|
972 |
*
|
973 |
* @param integer $x the row to fetch
|
974 |
* @param integer $y the column to fetch
|
@@ -990,57 +582,7 @@ class PMXI_CsvParser
|
|
990 |
/**
|
991 |
* cell value filler
|
992 |
*
|
993 |
-
* replaces the value of a specific cell
|
994 |
-
*
|
995 |
-
* sample of a csv file "my_cool.csv"
|
996 |
-
*
|
997 |
-
* <code>
|
998 |
-
* name,age,skill
|
999 |
-
* john,13,knows magic
|
1000 |
-
* tanaka,8,makes sushi
|
1001 |
-
* jose,5,dances salsa
|
1002 |
-
* </code>
|
1003 |
-
*
|
1004 |
-
* php implementation
|
1005 |
-
*
|
1006 |
-
* <code>
|
1007 |
-
*
|
1008 |
-
* $csv = new File_CSV_DataSource;
|
1009 |
-
*
|
1010 |
-
* // load the csv file
|
1011 |
-
* $csv->load('my_cool.csv');
|
1012 |
-
*
|
1013 |
-
* // find out if the given coordinate is valid
|
1014 |
-
* if($csv->hasCell(1, 1)) {
|
1015 |
-
*
|
1016 |
-
* // if so grab that cell and dump it
|
1017 |
-
* var_export($csv->getCell(1, 1)); // '8'
|
1018 |
-
*
|
1019 |
-
* // replace the value of that cell
|
1020 |
-
* $csv->fillCell(1, 1, 'new value'); // true
|
1021 |
-
*
|
1022 |
-
* // output the new value of the cell
|
1023 |
-
* var_export($csv->getCell(1, 1)); // 'new value'
|
1024 |
-
*
|
1025 |
-
* }
|
1026 |
-
* </code>
|
1027 |
-
*
|
1028 |
-
* now lets try to grab the whole row
|
1029 |
-
*
|
1030 |
-
* <code>
|
1031 |
-
* // show the whole row
|
1032 |
-
* var_export($csv->getRow(1));
|
1033 |
-
* </code>
|
1034 |
-
*
|
1035 |
-
* standard output
|
1036 |
-
*
|
1037 |
-
* <code>
|
1038 |
-
* array (
|
1039 |
-
* 0 => 'tanaka',
|
1040 |
-
* 1 => 'new value',
|
1041 |
-
* 2 => 'makes sushi',
|
1042 |
-
* )
|
1043 |
-
* </code>
|
1044 |
*
|
1045 |
* @param integer $x the row to fetch
|
1046 |
* @param integer $y the column to fetch
|
@@ -1062,37 +604,7 @@ class PMXI_CsvParser
|
|
1062 |
}
|
1063 |
|
1064 |
/**
|
1065 |
-
* checks if a coordinate is valid
|
1066 |
-
*
|
1067 |
-
* sample of a csv file "my_cool.csv"
|
1068 |
-
*
|
1069 |
-
* <code>
|
1070 |
-
* name,age,skill
|
1071 |
-
* john,13,knows magic
|
1072 |
-
* tanaka,8,makes sushi
|
1073 |
-
* jose,5,dances salsa
|
1074 |
-
* </code>
|
1075 |
-
*
|
1076 |
-
* load the csv file
|
1077 |
-
*
|
1078 |
-
* <code>
|
1079 |
-
* $csv = new File_CSV_DataSource;
|
1080 |
-
* var_export($csv->load('my_cool.csv')); // true if file is
|
1081 |
-
* // loaded
|
1082 |
-
* </code>
|
1083 |
-
*
|
1084 |
-
* find out if a coordinate is valid
|
1085 |
-
*
|
1086 |
-
* <code>
|
1087 |
-
* var_export($csv->hasCell(99, 3)); // false
|
1088 |
-
* </code>
|
1089 |
-
*
|
1090 |
-
* check again for a know valid coordinate and grab that cell
|
1091 |
-
*
|
1092 |
-
* <code>
|
1093 |
-
* var_export($csv->hasCell(1, 1)); // true
|
1094 |
-
* var_export($csv->getCell(1, 1)); // '8'
|
1095 |
-
* </code>
|
1096 |
*
|
1097 |
* @param mixed $x the row to fetch
|
1098 |
* @param mixed $y the column to fetch
|
@@ -1110,70 +622,7 @@ class PMXI_CsvParser
|
|
1110 |
/**
|
1111 |
* row fetcher
|
1112 |
*
|
1113 |
-
* Note: first row is zero
|
1114 |
-
*
|
1115 |
-
* sample of a csv file "my_cool.csv"
|
1116 |
-
*
|
1117 |
-
* <code>
|
1118 |
-
* name,age,skill
|
1119 |
-
* john,13,knows magic
|
1120 |
-
* tanaka,8,makes sushi
|
1121 |
-
* jose,5,dances salsa
|
1122 |
-
* </code>
|
1123 |
-
*
|
1124 |
-
* load the library and csv file
|
1125 |
-
*
|
1126 |
-
* <code>
|
1127 |
-
* require_once 'File/CSV/DataSource.php';
|
1128 |
-
* $csv = new File_CSV_DataSource;
|
1129 |
-
* $csv->load('my_cool.csv');
|
1130 |
-
* </code>
|
1131 |
-
*
|
1132 |
-
* lets dump currently loaded data
|
1133 |
-
* <code>
|
1134 |
-
* var_export($csv->connect());
|
1135 |
-
* </code>
|
1136 |
-
*
|
1137 |
-
* output
|
1138 |
-
*
|
1139 |
-
* <code>
|
1140 |
-
* array (
|
1141 |
-
* 0 =>
|
1142 |
-
* array (
|
1143 |
-
* 'name' => 'john',
|
1144 |
-
* 'age' => '13',
|
1145 |
-
* 'skill' => 'knows magic',
|
1146 |
-
* ),
|
1147 |
-
* 1 =>
|
1148 |
-
* array (
|
1149 |
-
* 'name' => 'tanaka',
|
1150 |
-
* 'age' => '8',
|
1151 |
-
* 'skill' => 'makes sushi',
|
1152 |
-
* ),
|
1153 |
-
* 2 =>
|
1154 |
-
* array (
|
1155 |
-
* 'name' => 'jose',
|
1156 |
-
* 'age' => '5',
|
1157 |
-
* 'skill' => 'dances salsa',
|
1158 |
-
* ),
|
1159 |
-
* )
|
1160 |
-
* </code>
|
1161 |
-
*
|
1162 |
-
* Now let's fetch the second row
|
1163 |
-
*
|
1164 |
-
* <code>
|
1165 |
-
* var_export($csv->getRow(1));
|
1166 |
-
* </code>
|
1167 |
-
*
|
1168 |
-
* output
|
1169 |
-
*
|
1170 |
-
* <code>
|
1171 |
-
* array (
|
1172 |
-
* 0 => 'tanaka',
|
1173 |
-
* 1 => '8',
|
1174 |
-
* 2 => 'makes sushi',
|
1175 |
-
* )
|
1176 |
-
* </code>
|
1177 |
*
|
1178 |
* @param integer $number the row number to fetch
|
1179 |
*
|
@@ -1197,98 +646,7 @@ class PMXI_CsvParser
|
|
1197 |
* - all rows if no $range argument is given
|
1198 |
* - a range of rows identified by their key
|
1199 |
* - if rows in range are not found nothing is retrived instead
|
1200 |
-
* - if no rows were found an empty array is returned
|
1201 |
-
*
|
1202 |
-
* sample of a csv file "my_cool.csv"
|
1203 |
-
*
|
1204 |
-
* <code>
|
1205 |
-
* name,age,skill
|
1206 |
-
* john,13,knows magic
|
1207 |
-
* tanaka,8,makes sushi
|
1208 |
-
* jose,5,dances salsa
|
1209 |
-
* </code>
|
1210 |
-
*
|
1211 |
-
* load the library and csv file
|
1212 |
-
*
|
1213 |
-
* <code>
|
1214 |
-
* require_once 'File/CSV/DataSource.php';
|
1215 |
-
* $csv = new File_CSV_DataSource;
|
1216 |
-
* $csv->load('my_cool.csv');
|
1217 |
-
* </code>
|
1218 |
-
*
|
1219 |
-
* lets dump currently loaded data
|
1220 |
-
* <code>
|
1221 |
-
* var_export($csv->connect());
|
1222 |
-
* </code>
|
1223 |
-
*
|
1224 |
-
* output
|
1225 |
-
*
|
1226 |
-
* <code>
|
1227 |
-
* array (
|
1228 |
-
* 0 =>
|
1229 |
-
* array (
|
1230 |
-
* 'name' => 'john',
|
1231 |
-
* 'age' => '13',
|
1232 |
-
* 'skill' => 'knows magic',
|
1233 |
-
* ),
|
1234 |
-
* 1 =>
|
1235 |
-
* array (
|
1236 |
-
* 'name' => 'tanaka',
|
1237 |
-
* 'age' => '8',
|
1238 |
-
* 'skill' => 'makes sushi',
|
1239 |
-
* ),
|
1240 |
-
* 2 =>
|
1241 |
-
* array (
|
1242 |
-
* 'name' => 'jose',
|
1243 |
-
* 'age' => '5',
|
1244 |
-
* 'skill' => 'dances salsa',
|
1245 |
-
* ),
|
1246 |
-
* )
|
1247 |
-
* </code>
|
1248 |
-
*
|
1249 |
-
* now get the second and thirdh row
|
1250 |
-
*
|
1251 |
-
* <code>
|
1252 |
-
* var_export($csv->getRows(array(1, 2)));
|
1253 |
-
* </code>
|
1254 |
-
*
|
1255 |
-
* output
|
1256 |
-
*
|
1257 |
-
* <code>
|
1258 |
-
* array (
|
1259 |
-
* 0 =>
|
1260 |
-
* array (
|
1261 |
-
* 0 => 'tanaka',
|
1262 |
-
* 1 => '8',
|
1263 |
-
* 2 => 'makes sushi',
|
1264 |
-
* ),
|
1265 |
-
* 1 =>
|
1266 |
-
* array (
|
1267 |
-
* 0 => 'jose',
|
1268 |
-
* 1 => '5',
|
1269 |
-
* 2 => 'dances salsa',
|
1270 |
-
* ),
|
1271 |
-
* )
|
1272 |
-
* </code>
|
1273 |
-
*
|
1274 |
-
* now lets try something odd and the goodie third row
|
1275 |
-
*
|
1276 |
-
* <code>
|
1277 |
-
* var_export($csv->getRows(array(9, 2)));
|
1278 |
-
* </code>
|
1279 |
-
*
|
1280 |
-
* output
|
1281 |
-
*
|
1282 |
-
* <code>
|
1283 |
-
* array (
|
1284 |
-
* 0 =>
|
1285 |
-
* array (
|
1286 |
-
* 0 => 'jose',
|
1287 |
-
* 1 => '5',
|
1288 |
-
* 2 => 'dances salsa',
|
1289 |
-
* ),
|
1290 |
-
* )
|
1291 |
-
* </code>
|
1292 |
*
|
1293 |
* @param array $range a list of rows to retrive
|
1294 |
*
|
@@ -1319,23 +677,6 @@ class PMXI_CsvParser
|
|
1319 |
*
|
1320 |
* This function will exclude the headers
|
1321 |
*
|
1322 |
-
* sample of a csv file "my_cool.csv"
|
1323 |
-
*
|
1324 |
-
* <code>
|
1325 |
-
* name,age,skill
|
1326 |
-
* john,13,knows magic
|
1327 |
-
* tanaka,8,makes sushi
|
1328 |
-
* jose,5,dances salsa
|
1329 |
-
* </code>
|
1330 |
-
*
|
1331 |
-
* php implementation
|
1332 |
-
*
|
1333 |
-
* <code>
|
1334 |
-
* $csv = new File_CSV_DataSource;
|
1335 |
-
* $csv->load('my_cool.csv');
|
1336 |
-
* var_export($csv->countRows()); // returns 3
|
1337 |
-
* </code>
|
1338 |
-
*
|
1339 |
* @access public
|
1340 |
* @return integer
|
1341 |
*/
|
@@ -1349,116 +690,6 @@ class PMXI_CsvParser
|
|
1349 |
*
|
1350 |
* Aggregates one more row to the currently loaded dataset
|
1351 |
*
|
1352 |
-
* sample of a csv file "my_cool.csv"
|
1353 |
-
*
|
1354 |
-
* <code>
|
1355 |
-
* name,age,skill
|
1356 |
-
* john,13,knows magic
|
1357 |
-
* tanaka,8,makes sushi
|
1358 |
-
* jose,5,dances salsa
|
1359 |
-
* </code>
|
1360 |
-
*
|
1361 |
-
*
|
1362 |
-
* first let's load the file and output whatever was retrived.
|
1363 |
-
*
|
1364 |
-
* <code>
|
1365 |
-
* require_once 'File/CSV/DataSource.php';
|
1366 |
-
* $csv = new File_CSV_DataSource;
|
1367 |
-
* $csv->load('my_cool.csv');
|
1368 |
-
* var_export($csv->connect());
|
1369 |
-
* </code>
|
1370 |
-
*
|
1371 |
-
* output
|
1372 |
-
*
|
1373 |
-
* <code>
|
1374 |
-
*
|
1375 |
-
* array (
|
1376 |
-
* 0 =>
|
1377 |
-
* array (
|
1378 |
-
* 'name' => 'john',
|
1379 |
-
* 'age' => '13',
|
1380 |
-
* 'skill' => 'knows magic',
|
1381 |
-
* ),
|
1382 |
-
* 1 =>
|
1383 |
-
* array (
|
1384 |
-
* 'name' => 'tanaka',
|
1385 |
-
* 'age' => '8',
|
1386 |
-
* 'skill' => 'makes sushi',
|
1387 |
-
* ),
|
1388 |
-
* 2 =>
|
1389 |
-
* array (
|
1390 |
-
* 'name' => 'jose',
|
1391 |
-
* 'age' => '5',
|
1392 |
-
* 'skill' => 'dances salsa',
|
1393 |
-
* ),
|
1394 |
-
* )
|
1395 |
-
* </code>
|
1396 |
-
*
|
1397 |
-
* now lets do some modifications, let's try adding three rows.
|
1398 |
-
*
|
1399 |
-
* <code>
|
1400 |
-
* var_export($csv->appendRow(1));
|
1401 |
-
* var_export($csv->appendRow('2'));
|
1402 |
-
* var_export($csv->appendRow(array(3, 3, 3)));
|
1403 |
-
* </code>
|
1404 |
-
*
|
1405 |
-
* output
|
1406 |
-
*
|
1407 |
-
* <code>
|
1408 |
-
* true
|
1409 |
-
* true
|
1410 |
-
* true
|
1411 |
-
* </code>
|
1412 |
-
*
|
1413 |
-
* and now let's try to see what has changed
|
1414 |
-
*
|
1415 |
-
* <code>
|
1416 |
-
* var_export($csv->connect());
|
1417 |
-
* </code>
|
1418 |
-
*
|
1419 |
-
* output
|
1420 |
-
*
|
1421 |
-
* <code>
|
1422 |
-
* array (
|
1423 |
-
* 0 =>
|
1424 |
-
* array (
|
1425 |
-
* 'name' => 'john',
|
1426 |
-
* 'age' => '13',
|
1427 |
-
* 'skill' => 'knows magic',
|
1428 |
-
* ),
|
1429 |
-
* 1 =>
|
1430 |
-
* array (
|
1431 |
-
* 'name' => 'tanaka',
|
1432 |
-
* 'age' => '8',
|
1433 |
-
* 'skill' => 'makes sushi',
|
1434 |
-
* ),
|
1435 |
-
* 2 =>
|
1436 |
-
* array (
|
1437 |
-
* 'name' => 'jose',
|
1438 |
-
* 'age' => '5',
|
1439 |
-
* 'skill' => 'dances salsa',
|
1440 |
-
* ),
|
1441 |
-
* 3 =>
|
1442 |
-
* array (
|
1443 |
-
* 'name' => 1,
|
1444 |
-
* 'age' => 1,
|
1445 |
-
* 'skill' => 1,
|
1446 |
-
* ),
|
1447 |
-
* 4 =>
|
1448 |
-
* array (
|
1449 |
-
* 'name' => '2',
|
1450 |
-
* 'age' => '2',
|
1451 |
-
* 'skill' => '2',
|
1452 |
-
* ),
|
1453 |
-
* 5 =>
|
1454 |
-
* array (
|
1455 |
-
* 'name' => 3,
|
1456 |
-
* 'age' => 3,
|
1457 |
-
* 'skill' => 3,
|
1458 |
-
* ),
|
1459 |
-
* )
|
1460 |
-
* </code>
|
1461 |
-
*
|
1462 |
* @param array $values the values to be appended to the row
|
1463 |
*
|
1464 |
* @access public
|
@@ -1474,111 +705,7 @@ class PMXI_CsvParser
|
|
1474 |
/**
|
1475 |
* fillRow
|
1476 |
*
|
1477 |
-
* Replaces the contents of cells in one given row with $values.
|
1478 |
-
*
|
1479 |
-
* sample of a csv file "my_cool.csv"
|
1480 |
-
*
|
1481 |
-
* <code>
|
1482 |
-
* name,age,skill
|
1483 |
-
* john,13,knows magic
|
1484 |
-
* tanaka,8,makes sushi
|
1485 |
-
* jose,5,dances salsa
|
1486 |
-
* </code>
|
1487 |
-
*
|
1488 |
-
* if we load the csv file and fill the second row with new data?
|
1489 |
-
*
|
1490 |
-
* <code>
|
1491 |
-
* // load the library
|
1492 |
-
* require_once 'File/CSV/DataSource.php';
|
1493 |
-
* $csv = new File_CSV_DataSource;
|
1494 |
-
*
|
1495 |
-
* // load csv file
|
1496 |
-
* $csv->load('my_cool.csv');
|
1497 |
-
*
|
1498 |
-
* // fill exitent row
|
1499 |
-
* var_export($csv->fillRow(1, 'x'));
|
1500 |
-
* </code>
|
1501 |
-
*
|
1502 |
-
* output
|
1503 |
-
*
|
1504 |
-
* <code>
|
1505 |
-
* true
|
1506 |
-
* </code>
|
1507 |
-
*
|
1508 |
-
* now let's dump whatever we have changed
|
1509 |
-
*
|
1510 |
-
* <code>
|
1511 |
-
* var_export($csv->connect());
|
1512 |
-
* </code>
|
1513 |
-
*
|
1514 |
-
* output
|
1515 |
-
*
|
1516 |
-
* <code>
|
1517 |
-
* array (
|
1518 |
-
* 0 =>
|
1519 |
-
* array (
|
1520 |
-
* 'name' => 'john',
|
1521 |
-
* 'age' => '13',
|
1522 |
-
* 'skill' => 'knows magic',
|
1523 |
-
* ),
|
1524 |
-
* 1 =>
|
1525 |
-
* array (
|
1526 |
-
* 'name' => 'x',
|
1527 |
-
* 'age' => 'x',
|
1528 |
-
* 'skill' => 'x',
|
1529 |
-
* ),
|
1530 |
-
* 2 =>
|
1531 |
-
* array (
|
1532 |
-
* 'name' => 'jose',
|
1533 |
-
* 'age' => '5',
|
1534 |
-
* 'skill' => 'dances salsa',
|
1535 |
-
* ),
|
1536 |
-
* )
|
1537 |
-
* </code>
|
1538 |
-
*
|
1539 |
-
* now lets try to fill the row with specific data for each cell
|
1540 |
-
*
|
1541 |
-
* <code>
|
1542 |
-
* var_export($csv->fillRow(1, array(1, 2, 3)));
|
1543 |
-
* </code>
|
1544 |
-
*
|
1545 |
-
* output
|
1546 |
-
*
|
1547 |
-
* <code>
|
1548 |
-
* true
|
1549 |
-
* </code>
|
1550 |
-
*
|
1551 |
-
* and dump the results
|
1552 |
-
*
|
1553 |
-
* <code>
|
1554 |
-
* var_export($csv->connect());
|
1555 |
-
* </code>
|
1556 |
-
*
|
1557 |
-
* output
|
1558 |
-
*
|
1559 |
-
* <code>
|
1560 |
-
*
|
1561 |
-
* array (
|
1562 |
-
* 0 =>
|
1563 |
-
* array (
|
1564 |
-
* 'name' => 'john',
|
1565 |
-
* 'age' => '13',
|
1566 |
-
* 'skill' => 'knows magic',
|
1567 |
-
* ),
|
1568 |
-
* 1 =>
|
1569 |
-
* array (
|
1570 |
-
* 'name' => 1,
|
1571 |
-
* 'age' => 2,
|
1572 |
-
* 'skill' => 3,
|
1573 |
-
* ),
|
1574 |
-
* 2 =>
|
1575 |
-
* array (
|
1576 |
-
* 'name' => 'jose',
|
1577 |
-
* 'age' => '5',
|
1578 |
-
* 'skill' => 'dances salsa',
|
1579 |
-
* ),
|
1580 |
-
* )
|
1581 |
-
* </code>
|
1582 |
*
|
1583 |
* @param integer $row the row to fill identified by its key
|
1584 |
* @param mixed $values the value to use, if a string or number
|
@@ -1617,72 +744,7 @@ class PMXI_CsvParser
|
|
1617 |
* row existance checker
|
1618 |
*
|
1619 |
* Scans currently loaded dataset and
|
1620 |
-
* checks if a given row identified by $number exists
|
1621 |
-
*
|
1622 |
-
* sample of a csv file "my_cool.csv"
|
1623 |
-
*
|
1624 |
-
* <code>
|
1625 |
-
* name,age,skill
|
1626 |
-
* john,13,knows magic
|
1627 |
-
* tanaka,8,makes sushi
|
1628 |
-
* jose,5,dances salsa
|
1629 |
-
* </code>
|
1630 |
-
*
|
1631 |
-
* load library and csv file
|
1632 |
-
*
|
1633 |
-
* <code>
|
1634 |
-
* require_once 'File/CSV/DataSource.php';
|
1635 |
-
* $csv = new File_CSV_DataSource;
|
1636 |
-
* $csv->load('my_cool.csv');
|
1637 |
-
* </code>
|
1638 |
-
*
|
1639 |
-
* build a relationship and dump it so we can see the rows we will
|
1640 |
-
* be working with
|
1641 |
-
*
|
1642 |
-
* <code>
|
1643 |
-
* var_export($csv->connect());
|
1644 |
-
* </code>
|
1645 |
-
*
|
1646 |
-
* output
|
1647 |
-
*
|
1648 |
-
* <code>
|
1649 |
-
* array (
|
1650 |
-
* 0 =>
|
1651 |
-
* array (
|
1652 |
-
* 'name' => 'john',
|
1653 |
-
* 'age' => '13',
|
1654 |
-
* 'skill' => 'knows magic',
|
1655 |
-
* ),
|
1656 |
-
* 1 => // THIS ROW EXISTS!!!
|
1657 |
-
* array (
|
1658 |
-
* 'name' => 'tanaka',
|
1659 |
-
* 'age' => '8',
|
1660 |
-
* 'skill' => 'makes sushi',
|
1661 |
-
* ),
|
1662 |
-
* 2 =>
|
1663 |
-
* array (
|
1664 |
-
* 'name' => 'jose',
|
1665 |
-
* 'age' => '5',
|
1666 |
-
* 'skill' => 'dances salsa',
|
1667 |
-
* ),
|
1668 |
-
* )
|
1669 |
-
* </code>
|
1670 |
-
*
|
1671 |
-
* now lets check for row existance
|
1672 |
-
*
|
1673 |
-
* <code>
|
1674 |
-
* var_export($csv->hasRow(1));
|
1675 |
-
* var_export($csv->hasRow(-1));
|
1676 |
-
* var_export($csv->hasRow(9999));
|
1677 |
-
* </code>
|
1678 |
-
*
|
1679 |
-
* output
|
1680 |
-
*
|
1681 |
-
* <code>
|
1682 |
-
* true
|
1683 |
-
* false
|
1684 |
-
* false
|
1685 |
-
* </code>
|
1686 |
*
|
1687 |
* @param mixed $number a numeric value that identifies the row
|
1688 |
* you are trying to fetch.
|
@@ -1700,88 +762,7 @@ class PMXI_CsvParser
|
|
1700 |
* row remover
|
1701 |
*
|
1702 |
* removes one row from the current data set.
|
1703 |
-
*
|
1704 |
-
* sample of a csv file "my_cool.csv"
|
1705 |
-
*
|
1706 |
-
* <code>
|
1707 |
-
* name,age,skill
|
1708 |
-
* john,13,knows magic
|
1709 |
-
* tanaka,8,makes sushi
|
1710 |
-
* jose,5,dances salsa
|
1711 |
-
* </code>
|
1712 |
-
*
|
1713 |
-
* first let's load the file and output whatever was retrived.
|
1714 |
-
*
|
1715 |
-
* <code>
|
1716 |
-
* require_once 'File/CSV/DataSource.php';
|
1717 |
-
* $csv = new File_CSV_DataSource;
|
1718 |
-
* $csv->load('my_cool.csv');
|
1719 |
-
* var_export($csv->connect());
|
1720 |
-
* </code>
|
1721 |
-
*
|
1722 |
-
* output
|
1723 |
-
*
|
1724 |
-
* <code>
|
1725 |
-
*
|
1726 |
-
* array (
|
1727 |
-
* 0 =>
|
1728 |
-
* array (
|
1729 |
-
* 'name' => 'john',
|
1730 |
-
* 'age' => '13',
|
1731 |
-
* 'skill' => 'knows magic',
|
1732 |
-
* ),
|
1733 |
-
* 1 =>
|
1734 |
-
* array (
|
1735 |
-
* 'name' => 'tanaka',
|
1736 |
-
* 'age' => '8',
|
1737 |
-
* 'skill' => 'makes sushi',
|
1738 |
-
* ),
|
1739 |
-
* 2 =>
|
1740 |
-
* array (
|
1741 |
-
* 'name' => 'jose',
|
1742 |
-
* 'age' => '5',
|
1743 |
-
* 'skill' => 'dances salsa',
|
1744 |
-
* ),
|
1745 |
-
* )
|
1746 |
-
* </code>
|
1747 |
-
*
|
1748 |
-
* now lets remove the second row
|
1749 |
-
*
|
1750 |
-
* <code>
|
1751 |
-
* var_export($csv->removeRow(1));
|
1752 |
-
* </code>
|
1753 |
-
*
|
1754 |
-
* output
|
1755 |
-
*
|
1756 |
-
* <code>
|
1757 |
-
* true
|
1758 |
-
* </code>
|
1759 |
-
*
|
1760 |
-
* now lets dump again the data and see what changes have been
|
1761 |
-
* made
|
1762 |
-
*
|
1763 |
-
* <code>
|
1764 |
-
* var_export($csv->connect());
|
1765 |
-
* </code>
|
1766 |
-
*
|
1767 |
-
* output
|
1768 |
-
*
|
1769 |
-
* <code>
|
1770 |
-
* array (
|
1771 |
-
* 0 =>
|
1772 |
-
* array (
|
1773 |
-
* 'name' => 'john',
|
1774 |
-
* 'age' => '13',
|
1775 |
-
* 'skill' => 'knows magic',
|
1776 |
-
* ),
|
1777 |
-
* 1 =>
|
1778 |
-
* array (
|
1779 |
-
* 'name' => 'jose',
|
1780 |
-
* 'age' => '5',
|
1781 |
-
* 'skill' => 'dances salsa',
|
1782 |
-
* ),
|
1783 |
-
* )
|
1784 |
-
* </code>
|
1785 |
*
|
1786 |
* @param mixed $number the key that identifies that row
|
1787 |
*
|
@@ -1859,116 +840,29 @@ class PMXI_CsvParser
|
|
1859 |
foreach ($this->rows as $key => $row) {
|
1860 |
$item = array();
|
1861 |
foreach ($this->headers as $col => $value) {
|
1862 |
-
$item[$value] = $row[$col];
|
1863 |
}
|
1864 |
array_push($ret_arr, $item);
|
1865 |
unset($item);
|
1866 |
}
|
1867 |
return $ret_arr;
|
1868 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1869 |
|
1870 |
/**
|
1871 |
* header creator
|
1872 |
*
|
1873 |
* uses prefix and creates a header for each column suffixed by a
|
1874 |
-
* numeric value
|
1875 |
-
*
|
1876 |
-
* by default the first row is interpreted as headers but if we
|
1877 |
-
* have a csv file with data only and no headers it becomes really
|
1878 |
-
* annoying to work with the current loaded data.
|
1879 |
-
*
|
1880 |
-
* this function will create a set dinamically generated headers
|
1881 |
-
* and make the current headers accessable with the row handling
|
1882 |
-
* functions
|
1883 |
-
*
|
1884 |
-
* Note: that the csv file contains only data but no headers
|
1885 |
-
* sample of a csv file "my_cool.csv"
|
1886 |
-
*
|
1887 |
-
* <code>
|
1888 |
-
* john,13,knows magic
|
1889 |
-
* tanaka,8,makes sushi
|
1890 |
-
* jose,5,dances salsa
|
1891 |
-
* </code>
|
1892 |
-
*
|
1893 |
-
* checks if the csv file was loaded
|
1894 |
-
*
|
1895 |
-
* <code>
|
1896 |
-
* $csv = new File_CSV_DataSource;
|
1897 |
-
* if (!$csv->load('my_cool.csv')) {
|
1898 |
-
* die('can not load csv file');
|
1899 |
-
* }
|
1900 |
-
* </code>
|
1901 |
-
*
|
1902 |
-
* dump current headers
|
1903 |
-
*
|
1904 |
-
* <code>
|
1905 |
-
* var_export($csv->getHeaders());
|
1906 |
-
* </code>
|
1907 |
-
*
|
1908 |
-
* standard output
|
1909 |
-
*
|
1910 |
-
* <code>
|
1911 |
-
* array (
|
1912 |
-
* 0 => 'john',
|
1913 |
-
* 1 => '13',
|
1914 |
-
* 2 => 'knows magic',
|
1915 |
-
* )
|
1916 |
-
* </code>
|
1917 |
-
*
|
1918 |
-
* generate headers named 'column' suffixed by a number and interpret
|
1919 |
-
* the previous headers as rows.
|
1920 |
-
*
|
1921 |
-
* <code>
|
1922 |
-
* $csv->createHeaders('column')
|
1923 |
-
* </code>
|
1924 |
-
*
|
1925 |
-
* dump current headers
|
1926 |
-
*
|
1927 |
-
* <code>
|
1928 |
-
* var_export($csv->getHeaders());
|
1929 |
-
* </code>
|
1930 |
-
*
|
1931 |
-
* standard output
|
1932 |
-
*
|
1933 |
-
* <code>
|
1934 |
-
* array (
|
1935 |
-
* 0 => 'column_1',
|
1936 |
-
* 1 => 'column_2',
|
1937 |
-
* 2 => 'column_3',
|
1938 |
-
* )
|
1939 |
-
* </code>
|
1940 |
-
*
|
1941 |
-
* build a relationship and dump it
|
1942 |
-
*
|
1943 |
-
* <code>
|
1944 |
-
* var_export($csv->connect());
|
1945 |
-
* </code>
|
1946 |
-
*
|
1947 |
-
* output
|
1948 |
-
*
|
1949 |
-
* <code>
|
1950 |
-
*
|
1951 |
-
* array (
|
1952 |
-
* 0 =>
|
1953 |
-
* array (
|
1954 |
-
* 'column_1' => 'john',
|
1955 |
-
* 'column_2' => '13',
|
1956 |
-
* 'column_3' => 'knows magic',
|
1957 |
-
* ),
|
1958 |
-
* 1 =>
|
1959 |
-
* array (
|
1960 |
-
* 'column_1' => 'tanaka',
|
1961 |
-
* 'column_2' => '8',
|
1962 |
-
* 'column_3' => 'makes sushi',
|
1963 |
-
* ),
|
1964 |
-
* 2 =>
|
1965 |
-
* array (
|
1966 |
-
* 'column_1' => 'jose',
|
1967 |
-
* 'column_2' => '5',
|
1968 |
-
* 'column_3' => 'dances salsa',
|
1969 |
-
* ),
|
1970 |
-
* )
|
1971 |
-
* </code>
|
1972 |
*
|
1973 |
* @param string $prefix string to use as prefix for each
|
1974 |
* independent header
|
@@ -2000,123 +894,6 @@ class PMXI_CsvParser
|
|
2000 |
* uses a $list of values which wil be used to replace current
|
2001 |
* headers.
|
2002 |
*
|
2003 |
-
* Note: that given $list must match the length of all rows.
|
2004 |
-
* known as symmetric. see isSymmetric() and getAsymmetricRows() methods
|
2005 |
-
*
|
2006 |
-
* Also, that current headers will be used as first row of data
|
2007 |
-
* and consecuently all rows order will change with this action.
|
2008 |
-
*
|
2009 |
-
* sample of a csv file "my_cool.csv"
|
2010 |
-
*
|
2011 |
-
* <code>
|
2012 |
-
* name,age,skill
|
2013 |
-
* john,13,knows magic
|
2014 |
-
* tanaka,8,makes sushi
|
2015 |
-
* jose,5,dances salsa
|
2016 |
-
* </code>
|
2017 |
-
*
|
2018 |
-
* load the library and csv file
|
2019 |
-
*
|
2020 |
-
* <code>
|
2021 |
-
* require_once 'File/CSV/DataSource.php';
|
2022 |
-
* $csv = new File_CSV_DataSource;
|
2023 |
-
* $csv->load('my_cool.csv');
|
2024 |
-
* </code>
|
2025 |
-
*
|
2026 |
-
* lets dump currently loaded data
|
2027 |
-
* <code>
|
2028 |
-
* var_export($csv->connect());
|
2029 |
-
* </code>
|
2030 |
-
*
|
2031 |
-
* output
|
2032 |
-
*
|
2033 |
-
* <code>
|
2034 |
-
* array (
|
2035 |
-
* 0 =>
|
2036 |
-
* array (
|
2037 |
-
* 'name' => 'john',
|
2038 |
-
* 'age' => '13',
|
2039 |
-
* 'skill' => 'knows magic',
|
2040 |
-
* ),
|
2041 |
-
* 1 =>
|
2042 |
-
* array (
|
2043 |
-
* 'name' => 'tanaka',
|
2044 |
-
* 'age' => '8',
|
2045 |
-
* 'skill' => 'makes sushi',
|
2046 |
-
* ),
|
2047 |
-
* 2 =>
|
2048 |
-
* array (
|
2049 |
-
* 'name' => 'jose',
|
2050 |
-
* 'age' => '5',
|
2051 |
-
* 'skill' => 'dances salsa',
|
2052 |
-
* ),
|
2053 |
-
* )
|
2054 |
-
* </code>
|
2055 |
-
*
|
2056 |
-
* And now lets create a new set of headers and attempt to inject
|
2057 |
-
* them into the current loaded dataset
|
2058 |
-
*
|
2059 |
-
* <code>
|
2060 |
-
* $new_headers = array('a', 'b', 'c');
|
2061 |
-
* var_export($csv->setHeaders($new_headers));
|
2062 |
-
* </code>
|
2063 |
-
*
|
2064 |
-
* output
|
2065 |
-
*
|
2066 |
-
* <code>
|
2067 |
-
* true
|
2068 |
-
* </code>
|
2069 |
-
*
|
2070 |
-
* Now lets try the same with some headers that do not match the
|
2071 |
-
* current headers length. (this should fail)
|
2072 |
-
*
|
2073 |
-
* <code>
|
2074 |
-
* $new_headers = array('a', 'b');
|
2075 |
-
* var_export($csv->setHeaders($new_headers));
|
2076 |
-
* </code>
|
2077 |
-
*
|
2078 |
-
* output
|
2079 |
-
*
|
2080 |
-
* <code>
|
2081 |
-
* false
|
2082 |
-
* </code>
|
2083 |
-
*
|
2084 |
-
* now let's dump whatever we have changed
|
2085 |
-
*
|
2086 |
-
* <code>
|
2087 |
-
* var_export($csv->connect());
|
2088 |
-
* </code>
|
2089 |
-
*
|
2090 |
-
* output
|
2091 |
-
*
|
2092 |
-
* <code>
|
2093 |
-
* array (
|
2094 |
-
* 0 =>
|
2095 |
-
* array (
|
2096 |
-
* 'a' => 'name',
|
2097 |
-
* 'b' => 'age',
|
2098 |
-
* 'c' => 'skill',
|
2099 |
-
* ),
|
2100 |
-
* 1 =>
|
2101 |
-
* array (
|
2102 |
-
* 'a' => 'john',
|
2103 |
-
* 'b' => '13',
|
2104 |
-
* 'c' => 'knows magic',
|
2105 |
-
* ),
|
2106 |
-
* 2 =>
|
2107 |
-
* array (
|
2108 |
-
* 'a' => 'tanaka',
|
2109 |
-
* 'b' => '8',
|
2110 |
-
* 'c' => 'makes sushi',
|
2111 |
-
* ),
|
2112 |
-
* 3 =>
|
2113 |
-
* array (
|
2114 |
-
* 'a' => 'jose',
|
2115 |
-
* 'b' => '5',
|
2116 |
-
* 'c' => 'dances salsa',
|
2117 |
-
* ),
|
2118 |
-
* )
|
2119 |
-
* </code>
|
2120 |
*
|
2121 |
* @param array $list a collection of names to use as headers,
|
2122 |
*
|
@@ -2157,33 +934,62 @@ class PMXI_CsvParser
|
|
2157 |
$c = 0;
|
2158 |
$d = $this->settings['delimiter'];
|
2159 |
$e = $this->settings['escape'];
|
2160 |
-
$l = $this->settings['length'];
|
2161 |
-
|
2162 |
-
$res = fopen($this->_filename, 'r');
|
2163 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2164 |
$create_new_headers = false;
|
2165 |
|
2166 |
while ($keys = fgetcsv($res, $l, $d, $e)) {
|
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 |
}
|
2174 |
}
|
2175 |
$this->headers = $keys;
|
2176 |
-
|
2177 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2178 |
}
|
2179 |
|
2180 |
$c ++;
|
2181 |
}
|
2182 |
-
|
|
|
2183 |
fclose($res);
|
2184 |
-
$this->removeEmpty();
|
2185 |
-
|
2186 |
-
if ($create_new_headers) $this->createHeaders('column');
|
2187 |
|
2188 |
return true;
|
2189 |
}
|
@@ -2306,10 +1112,8 @@ class PMXI_CsvParser
|
|
2306 |
// specify allowed field delimiters
|
2307 |
$delimiters = array(
|
2308 |
'comma' => ',',
|
2309 |
-
'semicolon' => ';',
|
2310 |
-
'
|
2311 |
-
'pipe' => '|',
|
2312 |
-
'colon' => ':'
|
2313 |
);
|
2314 |
|
2315 |
// specify allowed line endings
|
@@ -2329,9 +1133,9 @@ class PMXI_CsvParser
|
|
2329 |
asort($line_result);
|
2330 |
|
2331 |
// log to output array
|
2332 |
-
$output['line_ending']['results']
|
2333 |
$output['line_ending']['count'] = end($line_result);
|
2334 |
-
$output['line_ending']['key']
|
2335 |
$output['line_ending']['value'] = $line_endings[$output['line_ending']['key']];
|
2336 |
$lines = explode($output['line_ending']['value'], $contents);
|
2337 |
|
@@ -2378,7 +1182,7 @@ class ArrayToXML
|
|
2378 |
* @return string XML
|
2379 |
*/
|
2380 |
public static function toXml($data, $rootNodeName = 'data', $xml=null)
|
2381 |
-
{
|
2382 |
// turn off compatibility mode as simple xml throws a wobbly if you don't.
|
2383 |
if (ini_get('zend.ze1_compatibility_mode') == 1)
|
2384 |
{
|
@@ -2399,7 +1203,7 @@ class ArrayToXML
|
|
2399 |
// make string key...
|
2400 |
$key = "node";
|
2401 |
}
|
2402 |
-
|
2403 |
// replace anything not alpha numeric
|
2404 |
$key = preg_replace('/[^a-z0-9_]/i', '', $key);
|
2405 |
|
@@ -2413,11 +1217,10 @@ class ArrayToXML
|
|
2413 |
else
|
2414 |
{
|
2415 |
// add single node.
|
2416 |
-
$value =
|
2417 |
$xml->addChild($key,$value);
|
2418 |
}
|
2419 |
-
|
2420 |
-
|
2421 |
}
|
2422 |
// pass back as string. or simple xml object if you want!
|
2423 |
return $xml->asXML();
|
71 |
'eol' => '',
|
72 |
'length' => 999999,
|
73 |
'escape' => '"'
|
74 |
+
),
|
75 |
+
|
76 |
+
$tmp_files = array(),
|
77 |
+
|
78 |
+
$xpath = '',
|
79 |
+
|
80 |
+
$large_import = false,
|
81 |
+
|
82 |
+
$xml_path = '';
|
83 |
|
84 |
protected
|
85 |
|
116 |
* @see load()
|
117 |
* @return void
|
118 |
*/
|
119 |
+
public function __construct($filename = null, $large_import = false, $xpath = '')
|
120 |
{
|
121 |
+
|
122 |
+
$this->large_import = $large_import;
|
123 |
+
$this->xpath = (!empty($xpath) ? $xpath : ((!empty($_POST['xpath'])) ? $_POST['xpath'] : '/node'));
|
124 |
|
125 |
ini_set( "display_errors", 0);
|
126 |
+
ini_set('auto_detect_line_endings', true);
|
127 |
|
128 |
$file_params = self::analyse_file($filename, 10);
|
129 |
|
139 |
*
|
140 |
* indicates the object which file is to be loaded
|
141 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
*
|
143 |
* @param string $filename the csv filename to load
|
144 |
*
|
158 |
*
|
159 |
* lets you define different settings for scanning
|
160 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
*
|
162 |
* @param mixed $array containing settings to use
|
163 |
*
|
175 |
*
|
176 |
* gets csv headers into an array
|
177 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
* @access public
|
179 |
* @return array
|
180 |
*/
|
201 |
*
|
202 |
* Attempts to create a relationship for every single cell that
|
203 |
* was captured and its corresponding header. The sample below shows
|
204 |
+
* how a connection/relationship is built.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
*
|
206 |
* @param array $columns the columns to connect, if nothing
|
207 |
* is given all headers will be used to create a connection
|
273 |
* lets assume that we add one more row to our csv file.
|
274 |
* that has only two values. Something like
|
275 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
276 |
* @access public
|
277 |
* @return array filled with rows that do not match headers
|
278 |
* @see getHeaders(), symmetrize(), isSymmetric(),
|
359 |
*
|
360 |
* Note $name is the same as the items returned by getHeaders()
|
361 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
362 |
* @param string $name the name of the column to fetch
|
363 |
*
|
364 |
* @access public
|
385 |
* checks if a column exists, columns are identified by their
|
386 |
* header name.
|
387 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
388 |
* @param string $string an item returned by getHeaders()
|
389 |
*
|
390 |
* @access public
|
400 |
* column appender
|
401 |
*
|
402 |
* Appends a column and each or all values in it can be
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
403 |
*
|
404 |
* @param string $column an item returned by getHeaders()
|
405 |
* @param mixed $values same as fillColumn()
|
436 |
*
|
437 |
* fills alll the data in the given column with $values
|
438 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
439 |
* @param mixed $column the column identified by a string
|
440 |
* @param mixed $values ither one of the following
|
441 |
* - (Number) will fill the whole column with the value of number
|
487 |
/**
|
488 |
* column remover
|
489 |
*
|
490 |
+
* Completly removes a whole column identified by $name
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
491 |
*
|
492 |
* @param string $name same as the ones returned by getHeaders();
|
493 |
*
|
560 |
/**
|
561 |
* cell fetcher
|
562 |
*
|
563 |
+
* gets the value of a specific cell by given coordinates
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
564 |
*
|
565 |
* @param integer $x the row to fetch
|
566 |
* @param integer $y the column to fetch
|
582 |
/**
|
583 |
* cell value filler
|
584 |
*
|
585 |
+
* replaces the value of a specific cell
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
586 |
*
|
587 |
* @param integer $x the row to fetch
|
588 |
* @param integer $y the column to fetch
|
604 |
}
|
605 |
|
606 |
/**
|
607 |
+
* checks if a coordinate is valid
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
608 |
*
|
609 |
* @param mixed $x the row to fetch
|
610 |
* @param mixed $y the column to fetch
|
622 |
/**
|
623 |
* row fetcher
|
624 |
*
|
625 |
+
* Note: first row is zero
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
626 |
*
|
627 |
* @param integer $number the row number to fetch
|
628 |
*
|
646 |
* - all rows if no $range argument is given
|
647 |
* - a range of rows identified by their key
|
648 |
* - if rows in range are not found nothing is retrived instead
|
649 |
+
* - if no rows were found an empty array is returned
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
650 |
*
|
651 |
* @param array $range a list of rows to retrive
|
652 |
*
|
677 |
*
|
678 |
* This function will exclude the headers
|
679 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
680 |
* @access public
|
681 |
* @return integer
|
682 |
*/
|
690 |
*
|
691 |
* Aggregates one more row to the currently loaded dataset
|
692 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
693 |
* @param array $values the values to be appended to the row
|
694 |
*
|
695 |
* @access public
|
705 |
/**
|
706 |
* fillRow
|
707 |
*
|
708 |
+
* Replaces the contents of cells in one given row with $values.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
709 |
*
|
710 |
* @param integer $row the row to fill identified by its key
|
711 |
* @param mixed $values the value to use, if a string or number
|
744 |
* row existance checker
|
745 |
*
|
746 |
* Scans currently loaded dataset and
|
747 |
+
* checks if a given row identified by $number exists
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
748 |
*
|
749 |
* @param mixed $number a numeric value that identifies the row
|
750 |
* you are trying to fetch.
|
762 |
* row remover
|
763 |
*
|
764 |
* removes one row from the current data set.
|
765 |
+
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
766 |
*
|
767 |
* @param mixed $number the key that identifies that row
|
768 |
*
|
840 |
foreach ($this->rows as $key => $row) {
|
841 |
$item = array();
|
842 |
foreach ($this->headers as $col => $value) {
|
843 |
+
$item[$value] = $this->fixEncoding($row[$col]);
|
844 |
}
|
845 |
array_push($ret_arr, $item);
|
846 |
unset($item);
|
847 |
}
|
848 |
return $ret_arr;
|
849 |
+
}
|
850 |
+
|
851 |
+
// Fixes the encoding to uf8
|
852 |
+
function fixEncoding($in_str)
|
853 |
+
{
|
854 |
+
$cur_encoding = mb_detect_encoding($in_str) ;
|
855 |
+
if($cur_encoding == "UTF-8" && mb_check_encoding($in_str,"UTF-8"))
|
856 |
+
return $in_str;
|
857 |
+
else
|
858 |
+
return utf8_encode($in_str);
|
859 |
+
} // fixEncoding
|
860 |
|
861 |
/**
|
862 |
* header creator
|
863 |
*
|
864 |
* uses prefix and creates a header for each column suffixed by a
|
865 |
+
* numeric value
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
866 |
*
|
867 |
* @param string $prefix string to use as prefix for each
|
868 |
* independent header
|
894 |
* uses a $list of values which wil be used to replace current
|
895 |
* headers.
|
896 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
897 |
*
|
898 |
* @param array $list a collection of names to use as headers,
|
899 |
*
|
934 |
$c = 0;
|
935 |
$d = $this->settings['delimiter'];
|
936 |
$e = $this->settings['escape'];
|
937 |
+
$l = $this->settings['length'];
|
|
|
|
|
938 |
|
939 |
+
$res = fopen($this->_filename, 'rb');
|
940 |
+
|
941 |
+
$wp_uploads = wp_upload_dir();
|
942 |
+
if ($this->large_import){
|
943 |
+
$tmpname = wp_unique_filename($wp_uploads['path'], str_replace("csv", "xml", basename($this->_filename)));
|
944 |
+
$this->xml_path = $wp_uploads['path'] .'/'. $tmpname;
|
945 |
+
$fp = fopen($this->xml_path, 'w');
|
946 |
+
fwrite($fp, '<?xml version="1.0" encoding="utf-8"?><data>');
|
947 |
+
}
|
948 |
$create_new_headers = false;
|
949 |
|
950 |
while ($keys = fgetcsv($res, $l, $d, $e)) {
|
951 |
|
952 |
if ($c == 0) {
|
953 |
+
foreach ($keys as $key => $value) {
|
954 |
+
$value = trim(strtolower(preg_replace('/^[0-9]{1}/','el_', preg_replace('/[^a-z0-9_]/i', '', $value))));
|
955 |
+
$keys[$key] = (!empty($value)) ? $value : 'undefined'.$key;
|
956 |
if (preg_match('%\W(http:|https:|ftp:)$%i', $value) or is_numeric($value)) {
|
957 |
$create_new_headers = true;
|
958 |
break;
|
959 |
}
|
960 |
}
|
961 |
$this->headers = $keys;
|
962 |
+
|
963 |
+
if ($create_new_headers) $this->createHeaders('column');
|
964 |
+
|
965 |
+
} else {
|
966 |
+
|
967 |
+
if (!$this->large_import and empty($_POST['large_file'])) {
|
968 |
+
array_push($this->rows, $keys);
|
969 |
+
}
|
970 |
+
else if (!empty($keys[0])){
|
971 |
+
|
972 |
+
$chunk = array();
|
973 |
+
|
974 |
+
foreach ($this->headers as $key => $header) {
|
975 |
+
$chunk[$header] = $this->fixEncoding($keys[$key]);
|
976 |
+
}
|
977 |
+
|
978 |
+
if (!empty($chunk))
|
979 |
+
{
|
980 |
+
fwrite($fp, "<node>");
|
981 |
+
foreach ($chunk as $header => $value) fwrite($fp, "<".$header.">".$value."</".$header.">");
|
982 |
+
fwrite($fp, "</node>");
|
983 |
+
}
|
984 |
+
}
|
985 |
}
|
986 |
|
987 |
$c ++;
|
988 |
}
|
989 |
+
fwrite($fp, '</data>');
|
990 |
+
fclose($fp);
|
991 |
fclose($res);
|
992 |
+
$this->removeEmpty();
|
|
|
|
|
993 |
|
994 |
return true;
|
995 |
}
|
1112 |
// specify allowed field delimiters
|
1113 |
$delimiters = array(
|
1114 |
'comma' => ',',
|
1115 |
+
'semicolon' => ';',
|
1116 |
+
'pipe' => '|'
|
|
|
|
|
1117 |
);
|
1118 |
|
1119 |
// specify allowed line endings
|
1133 |
asort($line_result);
|
1134 |
|
1135 |
// log to output array
|
1136 |
+
$output['line_ending']['results'] = $line_result;
|
1137 |
$output['line_ending']['count'] = end($line_result);
|
1138 |
+
$output['line_ending']['key'] = key($line_result);
|
1139 |
$output['line_ending']['value'] = $line_endings[$output['line_ending']['key']];
|
1140 |
$lines = explode($output['line_ending']['value'], $contents);
|
1141 |
|
1182 |
* @return string XML
|
1183 |
*/
|
1184 |
public static function toXml($data, $rootNodeName = 'data', $xml=null)
|
1185 |
+
{
|
1186 |
// turn off compatibility mode as simple xml throws a wobbly if you don't.
|
1187 |
if (ini_get('zend.ze1_compatibility_mode') == 1)
|
1188 |
{
|
1203 |
// make string key...
|
1204 |
$key = "node";
|
1205 |
}
|
1206 |
+
|
1207 |
// replace anything not alpha numeric
|
1208 |
$key = preg_replace('/[^a-z0-9_]/i', '', $key);
|
1209 |
|
1217 |
else
|
1218 |
{
|
1219 |
// add single node.
|
1220 |
+
$value = htmlspecialchars($value);
|
1221 |
$xml->addChild($key,$value);
|
1222 |
}
|
1223 |
+
|
|
|
1224 |
}
|
1225 |
// pass back as string. or simple xml object if you want!
|
1226 |
return $xml->asXML();
|
libraries/XmlImportParser.php
CHANGED
@@ -49,7 +49,17 @@ class XmlImportParser {
|
|
49 |
// FIX: remove default namespace because libxml xpath implementation doesn't handle it properly
|
50 |
$xml and $xml = preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml);
|
51 |
|
52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
$this->rootNodeXPath = $rootNodeXPath;
|
54 |
$this->cachedTemplate = $cachedTemplate;
|
55 |
}
|
@@ -62,7 +72,7 @@ class XmlImportParser {
|
|
62 |
* @return array
|
63 |
*/
|
64 |
public function parse($records = array())
|
65 |
-
{
|
66 |
empty($records) or is_array($records) or $records = array($records);
|
67 |
|
68 |
$result = array();
|
@@ -70,7 +80,7 @@ class XmlImportParser {
|
|
70 |
$rootNodes = $this->xml->xpath($this->rootNodeXPath);
|
71 |
if ($rootNodes === false)
|
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];
|
49 |
// FIX: remove default namespace because libxml xpath implementation doesn't handle it properly
|
50 |
$xml and $xml = preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml);
|
51 |
|
52 |
+
libxml_use_internal_errors(true);
|
53 |
+
try{
|
54 |
+
$this->xml = new SimpleXMLElement($xml);
|
55 |
+
} catch (Exception $e){
|
56 |
+
try{
|
57 |
+
$this->xml = new SimpleXMLElement(utf8_encode($xml));
|
58 |
+
} catch (Exception $e){
|
59 |
+
throw new XmlImportException($e->getMessage());
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
$this->rootNodeXPath = $rootNodeXPath;
|
64 |
$this->cachedTemplate = $cachedTemplate;
|
65 |
}
|
72 |
* @return array
|
73 |
*/
|
74 |
public function parse($records = array())
|
75 |
+
{
|
76 |
empty($records) or is_array($records) or $records = array($records);
|
77 |
|
78 |
$result = array();
|
80 |
$rootNodes = $this->xml->xpath($this->rootNodeXPath);
|
81 |
if ($rootNodes === false)
|
82 |
throw new XmlImportException('Invalid root node XPath \'' . $this->rootNodeXPath . '\' specified');
|
83 |
+
|
84 |
for ($i = 0; $i < count($rootNodes); $i++) {
|
85 |
if (empty($records) or in_array($i + 1, $records)) {
|
86 |
$rootNode = $rootNodes[$i];
|
libraries/XmlImportTemplateCodeGenerator.php
CHANGED
@@ -12,7 +12,6 @@ require_once dirname(__FILE__) . '/ast/XmlImportAstInteger.php';
|
|
12 |
require_once dirname(__FILE__) . '/ast/XmlImportAstFloat.php';
|
13 |
require_once dirname(__FILE__) . '/ast/XmlImportAstString.php';
|
14 |
require_once dirname(__FILE__) . '/ast/XmlImportAstXPath.php';
|
15 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstFunction.php';
|
16 |
require_once dirname(__FILE__) . '/ast/XmlImportAstWith.php';
|
17 |
require_once dirname(__FILE__) . '/ast/XmlImportAstForeach.php';
|
18 |
require_once dirname(__FILE__) . '/ast/XmlImportAstIf.php';
|
@@ -92,11 +91,11 @@ class XmlImportTemplateCodeGenerator
|
|
92 |
$var = '$x' . $this->xmlVariableNumber++;
|
93 |
array_push($this->xmlStack, $var);
|
94 |
$result .= $this->openPhpTag() . $var . ' = $this->xml;' ;
|
95 |
-
}
|
96 |
$result .= $this->generateForSequence($this->sequence);
|
97 |
-
|
98 |
if (count($this->sequence->getVariables()))
|
99 |
-
{
|
100 |
array_pop($this->xmlStack);
|
101 |
}
|
102 |
if (is_null($filename))
|
@@ -122,7 +121,7 @@ class XmlImportTemplateCodeGenerator
|
|
122 |
{
|
123 |
$result .= $this->openPhpTag();
|
124 |
foreach ($sequence->getVariableDefinitions() as $xpath)
|
125 |
-
{
|
126 |
$result .= PHP_EOL . str_replace('{{XML}}', $this->xmlStack[count($this->xmlStack) - 1], $xpath);
|
127 |
}
|
128 |
$result .= PHP_EOL;
|
@@ -132,6 +131,7 @@ class XmlImportTemplateCodeGenerator
|
|
132 |
$result .= $this->generateForStatement($statement);
|
133 |
}
|
134 |
array_pop($this->sequenceStack);
|
|
|
135 |
return $result;
|
136 |
}
|
137 |
|
@@ -186,7 +186,7 @@ class XmlImportTemplateCodeGenerator
|
|
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)
|
@@ -228,22 +228,18 @@ class XmlImportTemplateCodeGenerator
|
|
228 |
$result = $expression->getValue();
|
229 |
break;
|
230 |
|
231 |
-
case 'XmlImportAstXPath':
|
232 |
if ($inPrint)
|
233 |
{
|
234 |
-
$variables = $this->sequenceStack[count($this->sequenceStack) - 1]->getVariables();
|
235 |
-
$result = '$this->getValue(' . $variables[$expression->getValue()] . ')';
|
236 |
}
|
237 |
else
|
238 |
-
{
|
239 |
-
$variables = $this->sequenceStack[count($this->sequenceStack) - 1]->getVariables();
|
240 |
-
$result = $variables[$expression->getValue()];
|
241 |
}
|
242 |
break;
|
243 |
-
|
244 |
-
case 'XmlImportAstFunction':
|
245 |
-
$result = $this->generateForFunction($expression);
|
246 |
-
break;
|
247 |
|
248 |
case 'XmlImportAstMath':
|
249 |
$result = $this->generateForMath($expression);
|
@@ -255,28 +251,7 @@ class XmlImportTemplateCodeGenerator
|
|
255 |
}
|
256 |
return $result;
|
257 |
}
|
258 |
-
|
259 |
-
/**
|
260 |
-
* Generates code for a function
|
261 |
-
*
|
262 |
-
* @param XmlImportAstFunction $function
|
263 |
-
* @return string
|
264 |
-
*/
|
265 |
-
private function generateForFunction(XmlImportAstFunction $function)
|
266 |
-
{
|
267 |
-
$result = $function->getName() . '(';
|
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 |
-
}
|
275 |
-
$result .= ')';
|
276 |
-
|
277 |
-
return $result;
|
278 |
-
}
|
279 |
-
|
280 |
/**
|
281 |
* Generates code for a function
|
282 |
*
|
@@ -303,36 +278,59 @@ class XmlImportTemplateCodeGenerator
|
|
303 |
*/
|
304 |
private function generateForSpintax(XmlImportAstSpintax $spintax)
|
305 |
{
|
306 |
-
$result
|
307 |
$arguments = $spintax->getArguments();
|
|
|
|
|
308 |
|
309 |
-
$
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
|
|
|
|
|
|
321 |
}
|
322 |
-
|
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
|
334 |
}
|
335 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
336 |
/**
|
337 |
* Add PHP open tag if needed
|
338 |
*
|
12 |
require_once dirname(__FILE__) . '/ast/XmlImportAstFloat.php';
|
13 |
require_once dirname(__FILE__) . '/ast/XmlImportAstString.php';
|
14 |
require_once dirname(__FILE__) . '/ast/XmlImportAstXPath.php';
|
|
|
15 |
require_once dirname(__FILE__) . '/ast/XmlImportAstWith.php';
|
16 |
require_once dirname(__FILE__) . '/ast/XmlImportAstForeach.php';
|
17 |
require_once dirname(__FILE__) . '/ast/XmlImportAstIf.php';
|
91 |
$var = '$x' . $this->xmlVariableNumber++;
|
92 |
array_push($this->xmlStack, $var);
|
93 |
$result .= $this->openPhpTag() . $var . ' = $this->xml;' ;
|
94 |
+
}
|
95 |
$result .= $this->generateForSequence($this->sequence);
|
96 |
+
|
97 |
if (count($this->sequence->getVariables()))
|
98 |
+
{
|
99 |
array_pop($this->xmlStack);
|
100 |
}
|
101 |
if (is_null($filename))
|
121 |
{
|
122 |
$result .= $this->openPhpTag();
|
123 |
foreach ($sequence->getVariableDefinitions() as $xpath)
|
124 |
+
{
|
125 |
$result .= PHP_EOL . str_replace('{{XML}}', $this->xmlStack[count($this->xmlStack) - 1], $xpath);
|
126 |
}
|
127 |
$result .= PHP_EOL;
|
131 |
$result .= $this->generateForStatement($statement);
|
132 |
}
|
133 |
array_pop($this->sequenceStack);
|
134 |
+
|
135 |
return $result;
|
136 |
}
|
137 |
|
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)
|
228 |
$result = $expression->getValue();
|
229 |
break;
|
230 |
|
231 |
+
case 'XmlImportAstXPath':
|
232 |
if ($inPrint)
|
233 |
{
|
234 |
+
$variables = $this->sequenceStack[count($this->sequenceStack) - 1]->getVariables();
|
235 |
+
$result = '$this->getValue(' . $variables[$expression->getValue()] . ')';
|
236 |
}
|
237 |
else
|
238 |
+
{
|
239 |
+
$variables = $this->sequenceStack[count($this->sequenceStack) - 1]->getVariables();
|
240 |
+
$result = $variables[$expression->getValue()];
|
241 |
}
|
242 |
break;
|
|
|
|
|
|
|
|
|
243 |
|
244 |
case 'XmlImportAstMath':
|
245 |
$result = $this->generateForMath($expression);
|
251 |
}
|
252 |
return $result;
|
253 |
}
|
254 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
255 |
/**
|
256 |
* Generates code for a function
|
257 |
*
|
278 |
*/
|
279 |
private function generateForSpintax(XmlImportAstSpintax $spintax)
|
280 |
{
|
281 |
+
$result = '';
|
282 |
$arguments = $spintax->getArguments();
|
283 |
+
$elements = array();
|
284 |
+
$buf = array();
|
285 |
|
286 |
+
for($i = 0; $i < count($arguments); $i++)
|
287 |
+
{
|
288 |
+
|
289 |
+
if ($arguments[$i]->getValue() != '|') array_push($buf, $this->generateForExpression($arguments[$i], true)); else { array_push($elements, $buf); $buf = array();}
|
290 |
+
|
291 |
+
}
|
292 |
+
|
293 |
+
array_push($elements, $buf);
|
294 |
+
|
295 |
+
if (!empty($elements) and is_array($elements)){
|
296 |
+
|
297 |
+
$spintax_arr = $this->generateVariation($elements);
|
298 |
+
|
299 |
+
foreach ($spintax_arr as $key => $value) {
|
300 |
+
$result .= "\"<p>\".".implode(".", $value).".\"</p>\""; if ($key != count($spintax_arr) - 1) $result .= ".";
|
301 |
}
|
302 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
303 |
}
|
304 |
|
305 |
+
return $result;
|
306 |
}
|
307 |
|
308 |
+
function generateVariation($A, $i = 0)
|
309 |
+
{
|
310 |
+
$result = array();
|
311 |
+
|
312 |
+
if ($i < count($A))
|
313 |
+
{
|
314 |
+
$variations = $this->generateVariation($A, $i + 1);
|
315 |
+
|
316 |
+
for ($j = 0; $j < count($A[$i]); $j++)
|
317 |
+
{
|
318 |
+
if ($variations)
|
319 |
+
{
|
320 |
+
foreach ($variations as $variation)
|
321 |
+
{
|
322 |
+
$result[] = array_merge(array($A[$i][$j]), $variation);
|
323 |
+
}
|
324 |
+
}
|
325 |
+
else
|
326 |
+
{
|
327 |
+
$result[] = array($A[$i][$j]);
|
328 |
+
}
|
329 |
+
}
|
330 |
+
}
|
331 |
+
|
332 |
+
return $result;
|
333 |
+
}
|
334 |
/**
|
335 |
* Add PHP open tag if needed
|
336 |
*
|
libraries/XmlImportTemplateParser.php
CHANGED
@@ -17,7 +17,6 @@ require_once dirname(__FILE__) . '/ast/XmlImportAstXPath.php';
|
|
17 |
require_once dirname(__FILE__) . '/ast/XmlImportAstString.php';
|
18 |
require_once dirname(__FILE__) . '/ast/XmlImportAstInteger.php';
|
19 |
require_once dirname(__FILE__) . '/ast/XmlImportAstFloat.php';
|
20 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstFunction.php';
|
21 |
|
22 |
/**
|
23 |
* Parses a list of nodes into AST (Abstract Syntax Tree)
|
@@ -161,7 +160,7 @@ class XmlImportTemplateParser
|
|
161 |
}
|
162 |
elseif($this->clauseStack[count($this->clauseStack) - 1] == XmlImportToken::KIND_ENDIF &&
|
163 |
in_array($this->tokens[$this->index + 1]->getKind(), array(XmlImportToken::KIND_ELSE, XmlImportToken::KIND_ELSEIF)))
|
164 |
-
{
|
165 |
if ($this->elseAllowed)
|
166 |
{
|
167 |
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_ELSE)
|
@@ -186,11 +185,8 @@ class XmlImportTemplateParser
|
|
186 |
{
|
187 |
if ($this->index + 1 == count($this->tokens))
|
188 |
throw new XmlImportException("Reached end of template but expression was expected");
|
189 |
-
|
190 |
-
|
191 |
-
return $this->parseFunction();
|
192 |
-
}
|
193 |
-
elseif($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_MATH)
|
194 |
{
|
195 |
return $this->parseMath();
|
196 |
}
|
@@ -200,7 +196,7 @@ class XmlImportTemplateParser
|
|
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;
|
206 |
}
|
@@ -218,43 +214,7 @@ class XmlImportTemplateParser
|
|
218 |
}
|
219 |
else
|
220 |
throw new XmlImportException("Unexpected token " . $this->tokens[$this->index + 1]->getKind());
|
221 |
-
}
|
222 |
-
|
223 |
-
/**
|
224 |
-
* Parses function
|
225 |
-
*
|
226 |
-
* @return XmlImportAstFunction
|
227 |
-
*/
|
228 |
-
private function parseFunction()
|
229 |
-
{
|
230 |
-
$function = new XmlImportAstFunction($this->tokens[++$this->index]->getValue());
|
231 |
-
if ($this->tokens[$this->index + 1]->getKind() != XmlImportToken::KIND_OPEN)
|
232 |
-
throw new XmlImportException ("Open brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
233 |
-
$this->index++;
|
234 |
-
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
235 |
-
{
|
236 |
-
$this->index++;
|
237 |
-
return $function;
|
238 |
-
}
|
239 |
-
else
|
240 |
-
{
|
241 |
-
while ($this->index < count($this->tokens) - 2)
|
242 |
-
{
|
243 |
-
$function->addArgument($this->parseExpression());
|
244 |
-
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
245 |
-
{
|
246 |
-
$this->index++;
|
247 |
-
return $function;
|
248 |
-
break;
|
249 |
-
}
|
250 |
-
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_COMMA)
|
251 |
-
$this->index++;
|
252 |
-
else
|
253 |
-
throw new XmlImportException("Comma or closing brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
254 |
-
}
|
255 |
-
throw new XmlImportException("Unexpected end of {$function->getName()} function argument list");
|
256 |
-
}
|
257 |
-
}
|
258 |
|
259 |
/**
|
260 |
* Parses function
|
@@ -309,20 +269,10 @@ class XmlImportTemplateParser
|
|
309 |
return $spintax;
|
310 |
}
|
311 |
else
|
312 |
-
{
|
313 |
while ($this->index < count($this->tokens) - 2)
|
314 |
-
{
|
315 |
-
|
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++;
|
@@ -330,11 +280,11 @@ class XmlImportTemplateParser
|
|
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
|
338 |
}
|
339 |
}
|
340 |
|
@@ -439,10 +389,11 @@ class XmlImportTemplateParser
|
|
439 |
}
|
440 |
if ($this->index + 1 < count($this->tokens) && $this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_ELSE)
|
441 |
{
|
442 |
-
$this->index++;
|
443 |
$if->addElseBody($this->parseSequence());
|
444 |
}
|
445 |
}
|
|
|
446 |
return $if;
|
447 |
}
|
448 |
}
|
17 |
require_once dirname(__FILE__) . '/ast/XmlImportAstString.php';
|
18 |
require_once dirname(__FILE__) . '/ast/XmlImportAstInteger.php';
|
19 |
require_once dirname(__FILE__) . '/ast/XmlImportAstFloat.php';
|
|
|
20 |
|
21 |
/**
|
22 |
* Parses a list of nodes into AST (Abstract Syntax Tree)
|
160 |
}
|
161 |
elseif($this->clauseStack[count($this->clauseStack) - 1] == XmlImportToken::KIND_ENDIF &&
|
162 |
in_array($this->tokens[$this->index + 1]->getKind(), array(XmlImportToken::KIND_ELSE, XmlImportToken::KIND_ELSEIF)))
|
163 |
+
{
|
164 |
if ($this->elseAllowed)
|
165 |
{
|
166 |
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_ELSE)
|
185 |
{
|
186 |
if ($this->index + 1 == count($this->tokens))
|
187 |
throw new XmlImportException("Reached end of template but expression was expected");
|
188 |
+
|
189 |
+
if($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_MATH)
|
|
|
|
|
|
|
190 |
{
|
191 |
return $this->parseMath();
|
192 |
}
|
196 |
}
|
197 |
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_XPATH)
|
198 |
{
|
199 |
+
$xpath = new XmlImportAstXPath($this->tokens[++$this->index]->getValue());
|
200 |
$this->sequenceStack[count($this->sequenceStack) - 1]->addVariable($xpath);
|
201 |
return $xpath;
|
202 |
}
|
214 |
}
|
215 |
else
|
216 |
throw new XmlImportException("Unexpected token " . $this->tokens[$this->index + 1]->getKind());
|
217 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
|
219 |
/**
|
220 |
* Parses function
|
269 |
return $spintax;
|
270 |
}
|
271 |
else
|
272 |
+
{
|
273 |
while ($this->index < count($this->tokens) - 2)
|
274 |
+
{
|
275 |
+
$spintax->addArgument($this->parseExpression());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
276 |
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
277 |
{
|
278 |
$this->index++;
|
280 |
break;
|
281 |
}
|
282 |
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_COMMA)
|
283 |
+
$this->index++;
|
284 |
else
|
285 |
throw new XmlImportException("Comma or closing brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
286 |
}
|
287 |
+
throw new XmlImportException("Unexpected end of {$function->getName()} function argument list");
|
288 |
}
|
289 |
}
|
290 |
|
389 |
}
|
390 |
if ($this->index + 1 < count($this->tokens) && $this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_ELSE)
|
391 |
{
|
392 |
+
$this->index++;
|
393 |
$if->addElseBody($this->parseSequence());
|
394 |
}
|
395 |
}
|
396 |
+
|
397 |
return $if;
|
398 |
}
|
399 |
}
|
libraries/ast/XmlImportAstSpintax.php
CHANGED
@@ -33,12 +33,9 @@ class XmlImportAstSpintax extends XmlImportAstExpression
|
|
33 |
*
|
34 |
* @param XmlImportAstExpression $argument
|
35 |
*/
|
36 |
-
public function addArgument(XmlImportAstExpression $argument
|
37 |
{
|
38 |
-
$this->arguments[] =
|
39 |
-
'argument' => $argument,
|
40 |
-
'type' => $type
|
41 |
-
);
|
42 |
}
|
43 |
|
44 |
/**
|
33 |
*
|
34 |
* @param XmlImportAstExpression $argument
|
35 |
*/
|
36 |
+
public function addArgument(XmlImportAstExpression $argument)
|
37 |
{
|
38 |
+
$this->arguments[] = $argument;
|
|
|
|
|
|
|
39 |
}
|
40 |
|
41 |
/**
|
libraries/pclzip.lib.php
ADDED
@@ -0,0 +1,5697 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// --------------------------------------------------------------------------------
|
3 |
+
// PhpConcept Library - Zip Module 2.8.2
|
4 |
+
// --------------------------------------------------------------------------------
|
5 |
+
// License GNU/LGPL - Vincent Blavet - August 2009
|
6 |
+
// http://www.phpconcept.net
|
7 |
+
// --------------------------------------------------------------------------------
|
8 |
+
//
|
9 |
+
// Presentation :
|
10 |
+
// PclZip is a PHP library that manage ZIP archives.
|
11 |
+
// So far tests show that archives generated by PclZip are readable by
|
12 |
+
// WinZip application and other tools.
|
13 |
+
//
|
14 |
+
// Description :
|
15 |
+
// See readme.txt and http://www.phpconcept.net
|
16 |
+
//
|
17 |
+
// Warning :
|
18 |
+
// This library and the associated files are non commercial, non professional
|
19 |
+
// work.
|
20 |
+
// It should not have unexpected results. However if any damage is caused by
|
21 |
+
// this software the author can not be responsible.
|
22 |
+
// The use of this software is at the risk of the user.
|
23 |
+
//
|
24 |
+
// --------------------------------------------------------------------------------
|
25 |
+
// $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $
|
26 |
+
// --------------------------------------------------------------------------------
|
27 |
+
|
28 |
+
// ----- Constants
|
29 |
+
if (!defined('PCLZIP_READ_BLOCK_SIZE')) {
|
30 |
+
define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
|
31 |
+
}
|
32 |
+
|
33 |
+
// ----- File list separator
|
34 |
+
// In version 1.x of PclZip, the separator for file list is a space
|
35 |
+
// (which is not a very smart choice, specifically for windows paths !).
|
36 |
+
// A better separator should be a comma (,). This constant gives you the
|
37 |
+
// abilty to change that.
|
38 |
+
// However notice that changing this value, may have impact on existing
|
39 |
+
// scripts, using space separated filenames.
|
40 |
+
// Recommanded values for compatibility with older versions :
|
41 |
+
//define( 'PCLZIP_SEPARATOR', ' ' );
|
42 |
+
// Recommanded values for smart separation of filenames.
|
43 |
+
if (!defined('PCLZIP_SEPARATOR')) {
|
44 |
+
define( 'PCLZIP_SEPARATOR', ',' );
|
45 |
+
}
|
46 |
+
|
47 |
+
// ----- Error configuration
|
48 |
+
// 0 : PclZip Class integrated error handling
|
49 |
+
// 1 : PclError external library error handling. By enabling this
|
50 |
+
// you must ensure that you have included PclError library.
|
51 |
+
// [2,...] : reserved for futur use
|
52 |
+
if (!defined('PCLZIP_ERROR_EXTERNAL')) {
|
53 |
+
define( 'PCLZIP_ERROR_EXTERNAL', 0 );
|
54 |
+
}
|
55 |
+
|
56 |
+
// ----- Optional static temporary directory
|
57 |
+
// By default temporary files are generated in the script current
|
58 |
+
// path.
|
59 |
+
// If defined :
|
60 |
+
// - MUST BE terminated by a '/'.
|
61 |
+
// - MUST be a valid, already created directory
|
62 |
+
// Samples :
|
63 |
+
// define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
|
64 |
+
// define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
|
65 |
+
|
66 |
+
$wp_uploads = wp_upload_dir();
|
67 |
+
|
68 |
+
if (!defined('PCLZIP_TEMPORARY_DIR')) {
|
69 |
+
define( 'PCLZIP_TEMPORARY_DIR', $wp_uploads['path'] );
|
70 |
+
}
|
71 |
+
|
72 |
+
// ----- Optional threshold ratio for use of temporary files
|
73 |
+
// Pclzip sense the size of the file to add/extract and decide to
|
74 |
+
// use or not temporary file. The algorythm is looking for
|
75 |
+
// memory_limit of PHP and apply a ratio.
|
76 |
+
// threshold = memory_limit * ratio.
|
77 |
+
// Recommended values are under 0.5. Default 0.47.
|
78 |
+
// Samples :
|
79 |
+
// define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 );
|
80 |
+
if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {
|
81 |
+
define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 );
|
82 |
+
}
|
83 |
+
|
84 |
+
// --------------------------------------------------------------------------------
|
85 |
+
// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
|
86 |
+
// --------------------------------------------------------------------------------
|
87 |
+
|
88 |
+
// ----- Global variables
|
89 |
+
$g_pclzip_version = "2.8.2";
|
90 |
+
|
91 |
+
// ----- Error codes
|
92 |
+
// -1 : Unable to open file in binary write mode
|
93 |
+
// -2 : Unable to open file in binary read mode
|
94 |
+
// -3 : Invalid parameters
|
95 |
+
// -4 : File does not exist
|
96 |
+
// -5 : Filename is too long (max. 255)
|
97 |
+
// -6 : Not a valid zip file
|
98 |
+
// -7 : Invalid extracted file size
|
99 |
+
// -8 : Unable to create directory
|
100 |
+
// -9 : Invalid archive extension
|
101 |
+
// -10 : Invalid archive format
|
102 |
+
// -11 : Unable to delete file (unlink)
|
103 |
+
// -12 : Unable to rename file (rename)
|
104 |
+
// -13 : Invalid header checksum
|
105 |
+
// -14 : Invalid archive size
|
106 |
+
define( 'PCLZIP_ERR_USER_ABORTED', 2 );
|
107 |
+
define( 'PCLZIP_ERR_NO_ERROR', 0 );
|
108 |
+
define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
|
109 |
+
define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
|
110 |
+
define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
|
111 |
+
define( 'PCLZIP_ERR_MISSING_FILE', -4 );
|
112 |
+
define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
|
113 |
+
define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
|
114 |
+
define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
|
115 |
+
define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
|
116 |
+
define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
|
117 |
+
define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
|
118 |
+
define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
|
119 |
+
define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
|
120 |
+
define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
|
121 |
+
define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
|
122 |
+
define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
|
123 |
+
define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
|
124 |
+
define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
|
125 |
+
define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
|
126 |
+
define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
|
127 |
+
define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
|
128 |
+
define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
|
129 |
+
|
130 |
+
// ----- Options values
|
131 |
+
define( 'PCLZIP_OPT_PATH', 77001 );
|
132 |
+
define( 'PCLZIP_OPT_ADD_PATH', 77002 );
|
133 |
+
define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
|
134 |
+
define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
|
135 |
+
define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
|
136 |
+
define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
|
137 |
+
define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
|
138 |
+
define( 'PCLZIP_OPT_BY_NAME', 77008 );
|
139 |
+
define( 'PCLZIP_OPT_BY_INDEX', 77009 );
|
140 |
+
define( 'PCLZIP_OPT_BY_EREG', 77010 );
|
141 |
+
define( 'PCLZIP_OPT_BY_PREG', 77011 );
|
142 |
+
define( 'PCLZIP_OPT_COMMENT', 77012 );
|
143 |
+
define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
|
144 |
+
define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
|
145 |
+
define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
|
146 |
+
define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
|
147 |
+
define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
|
148 |
+
// Having big trouble with crypt. Need to multiply 2 long int
|
149 |
+
// which is not correctly supported by PHP ...
|
150 |
+
//define( 'PCLZIP_OPT_CRYPT', 77018 );
|
151 |
+
define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
|
152 |
+
define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 );
|
153 |
+
define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias
|
154 |
+
define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 );
|
155 |
+
define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias
|
156 |
+
define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 );
|
157 |
+
define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias
|
158 |
+
|
159 |
+
// ----- File description attributes
|
160 |
+
define( 'PCLZIP_ATT_FILE_NAME', 79001 );
|
161 |
+
define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
|
162 |
+
define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
|
163 |
+
define( 'PCLZIP_ATT_FILE_MTIME', 79004 );
|
164 |
+
define( 'PCLZIP_ATT_FILE_CONTENT', 79005 );
|
165 |
+
define( 'PCLZIP_ATT_FILE_COMMENT', 79006 );
|
166 |
+
|
167 |
+
// ----- Call backs values
|
168 |
+
define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
|
169 |
+
define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
|
170 |
+
define( 'PCLZIP_CB_PRE_ADD', 78003 );
|
171 |
+
define( 'PCLZIP_CB_POST_ADD', 78004 );
|
172 |
+
/* For futur use
|
173 |
+
define( 'PCLZIP_CB_PRE_LIST', 78005 );
|
174 |
+
define( 'PCLZIP_CB_POST_LIST', 78006 );
|
175 |
+
define( 'PCLZIP_CB_PRE_DELETE', 78007 );
|
176 |
+
define( 'PCLZIP_CB_POST_DELETE', 78008 );
|
177 |
+
*/
|
178 |
+
|
179 |
+
// --------------------------------------------------------------------------------
|
180 |
+
// Class : PclZip
|
181 |
+
// Description :
|
182 |
+
// PclZip is the class that represent a Zip archive.
|
183 |
+
// The public methods allow the manipulation of the archive.
|
184 |
+
// Attributes :
|
185 |
+
// Attributes must not be accessed directly.
|
186 |
+
// Methods :
|
187 |
+
// PclZip() : Object creator
|
188 |
+
// create() : Creates the Zip archive
|
189 |
+
// listContent() : List the content of the Zip archive
|
190 |
+
// extract() : Extract the content of the archive
|
191 |
+
// properties() : List the properties of the archive
|
192 |
+
// --------------------------------------------------------------------------------
|
193 |
+
class PclZip
|
194 |
+
{
|
195 |
+
// ----- Filename of the zip file
|
196 |
+
var $zipname = '';
|
197 |
+
|
198 |
+
// ----- File descriptor of the zip file
|
199 |
+
var $zip_fd = 0;
|
200 |
+
|
201 |
+
// ----- Internal error handling
|
202 |
+
var $error_code = 1;
|
203 |
+
var $error_string = '';
|
204 |
+
|
205 |
+
// ----- Current status of the magic_quotes_runtime
|
206 |
+
// This value store the php configuration for magic_quotes
|
207 |
+
// The class can then disable the magic_quotes and reset it after
|
208 |
+
var $magic_quotes_status;
|
209 |
+
|
210 |
+
// --------------------------------------------------------------------------------
|
211 |
+
// Function : PclZip()
|
212 |
+
// Description :
|
213 |
+
// Creates a PclZip object and set the name of the associated Zip archive
|
214 |
+
// filename.
|
215 |
+
// Note that no real action is taken, if the archive does not exist it is not
|
216 |
+
// created. Use create() for that.
|
217 |
+
// --------------------------------------------------------------------------------
|
218 |
+
function PclZip($p_zipname)
|
219 |
+
{
|
220 |
+
|
221 |
+
// ----- Tests the zlib
|
222 |
+
if (!function_exists('gzopen'))
|
223 |
+
{
|
224 |
+
die('Abort '.basename(__FILE__).' : Missing zlib extensions');
|
225 |
+
}
|
226 |
+
|
227 |
+
// ----- Set the attributes
|
228 |
+
$this->zipname = $p_zipname;
|
229 |
+
$this->zip_fd = 0;
|
230 |
+
$this->magic_quotes_status = -1;
|
231 |
+
|
232 |
+
// ----- Return
|
233 |
+
return;
|
234 |
+
}
|
235 |
+
// --------------------------------------------------------------------------------
|
236 |
+
|
237 |
+
// --------------------------------------------------------------------------------
|
238 |
+
// Function :
|
239 |
+
// create($p_filelist, $p_add_dir="", $p_remove_dir="")
|
240 |
+
// create($p_filelist, $p_option, $p_option_value, ...)
|
241 |
+
// Description :
|
242 |
+
// This method supports two different synopsis. The first one is historical.
|
243 |
+
// This method creates a Zip Archive. The Zip file is created in the
|
244 |
+
// filesystem. The files and directories indicated in $p_filelist
|
245 |
+
// are added in the archive. See the parameters description for the
|
246 |
+
// supported format of $p_filelist.
|
247 |
+
// When a directory is in the list, the directory and its content is added
|
248 |
+
// in the archive.
|
249 |
+
// In this synopsis, the function takes an optional variable list of
|
250 |
+
// options. See bellow the supported options.
|
251 |
+
// Parameters :
|
252 |
+
// $p_filelist : An array containing file or directory names, or
|
253 |
+
// a string containing one filename or one directory name, or
|
254 |
+
// a string containing a list of filenames and/or directory
|
255 |
+
// names separated by spaces.
|
256 |
+
// $p_add_dir : A path to add before the real path of the archived file,
|
257 |
+
// in order to have it memorized in the archive.
|
258 |
+
// $p_remove_dir : A path to remove from the real path of the file to archive,
|
259 |
+
// in order to have a shorter path memorized in the archive.
|
260 |
+
// When $p_add_dir and $p_remove_dir are set, $p_remove_dir
|
261 |
+
// is removed first, before $p_add_dir is added.
|
262 |
+
// Options :
|
263 |
+
// PCLZIP_OPT_ADD_PATH :
|
264 |
+
// PCLZIP_OPT_REMOVE_PATH :
|
265 |
+
// PCLZIP_OPT_REMOVE_ALL_PATH :
|
266 |
+
// PCLZIP_OPT_COMMENT :
|
267 |
+
// PCLZIP_CB_PRE_ADD :
|
268 |
+
// PCLZIP_CB_POST_ADD :
|
269 |
+
// Return Values :
|
270 |
+
// 0 on failure,
|
271 |
+
// The list of the added files, with a status of the add action.
|
272 |
+
// (see PclZip::listContent() for list entry format)
|
273 |
+
// --------------------------------------------------------------------------------
|
274 |
+
function create($p_filelist)
|
275 |
+
{
|
276 |
+
$v_result=1;
|
277 |
+
|
278 |
+
// ----- Reset the error handler
|
279 |
+
$this->privErrorReset();
|
280 |
+
|
281 |
+
// ----- Set default values
|
282 |
+
$v_options = array();
|
283 |
+
$v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
|
284 |
+
|
285 |
+
// ----- Look for variable options arguments
|
286 |
+
$v_size = func_num_args();
|
287 |
+
|
288 |
+
// ----- Look for arguments
|
289 |
+
if ($v_size > 1) {
|
290 |
+
// ----- Get the arguments
|
291 |
+
$v_arg_list = func_get_args();
|
292 |
+
|
293 |
+
// ----- Remove from the options list the first argument
|
294 |
+
array_shift($v_arg_list);
|
295 |
+
$v_size--;
|
296 |
+
|
297 |
+
// ----- Look for first arg
|
298 |
+
if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
|
299 |
+
|
300 |
+
// ----- Parse the options
|
301 |
+
$v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
|
302 |
+
array (PCLZIP_OPT_REMOVE_PATH => 'optional',
|
303 |
+
PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
|
304 |
+
PCLZIP_OPT_ADD_PATH => 'optional',
|
305 |
+
PCLZIP_CB_PRE_ADD => 'optional',
|
306 |
+
PCLZIP_CB_POST_ADD => 'optional',
|
307 |
+
PCLZIP_OPT_NO_COMPRESSION => 'optional',
|
308 |
+
PCLZIP_OPT_COMMENT => 'optional',
|
309 |
+
PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
|
310 |
+
PCLZIP_OPT_TEMP_FILE_ON => 'optional',
|
311 |
+
PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
|
312 |
+
//, PCLZIP_OPT_CRYPT => 'optional'
|
313 |
+
));
|
314 |
+
if ($v_result != 1) {
|
315 |
+
return 0;
|
316 |
+
}
|
317 |
+
}
|
318 |
+
|
319 |
+
// ----- Look for 2 args
|
320 |
+
// Here we need to support the first historic synopsis of the
|
321 |
+
// method.
|
322 |
+
else {
|
323 |
+
|
324 |
+
// ----- Get the first argument
|
325 |
+
$v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
|
326 |
+
|
327 |
+
// ----- Look for the optional second argument
|
328 |
+
if ($v_size == 2) {
|
329 |
+
$v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
|
330 |
+
}
|
331 |
+
else if ($v_size > 2) {
|
332 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
|
333 |
+
"Invalid number / type of arguments");
|
334 |
+
return 0;
|
335 |
+
}
|
336 |
+
}
|
337 |
+
}
|
338 |
+
|
339 |
+
// ----- Look for default option values
|
340 |
+
$this->privOptionDefaultThreshold($v_options);
|
341 |
+
|
342 |
+
// ----- Init
|
343 |
+
$v_string_list = array();
|
344 |
+
$v_att_list = array();
|
345 |
+
$v_filedescr_list = array();
|
346 |
+
$p_result_list = array();
|
347 |
+
|
348 |
+
// ----- Look if the $p_filelist is really an array
|
349 |
+
if (is_array($p_filelist)) {
|
350 |
+
|
351 |
+
// ----- Look if the first element is also an array
|
352 |
+
// This will mean that this is a file description entry
|
353 |
+
if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
|
354 |
+
$v_att_list = $p_filelist;
|
355 |
+
}
|
356 |
+
|
357 |
+
// ----- The list is a list of string names
|
358 |
+
else {
|
359 |
+
$v_string_list = $p_filelist;
|
360 |
+
}
|
361 |
+
}
|
362 |
+
|
363 |
+
// ----- Look if the $p_filelist is a string
|
364 |
+
else if (is_string($p_filelist)) {
|
365 |
+
// ----- Create a list from the string
|
366 |
+
$v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
|
367 |
+
}
|
368 |
+
|
369 |
+
// ----- Invalid variable type for $p_filelist
|
370 |
+
else {
|
371 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
|
372 |
+
return 0;
|
373 |
+
}
|
374 |
+
|
375 |
+
// ----- Reformat the string list
|
376 |
+
if (sizeof($v_string_list) != 0) {
|
377 |
+
foreach ($v_string_list as $v_string) {
|
378 |
+
if ($v_string != '') {
|
379 |
+
$v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
|
380 |
+
}
|
381 |
+
else {
|
382 |
+
}
|
383 |
+
}
|
384 |
+
}
|
385 |
+
|
386 |
+
// ----- For each file in the list check the attributes
|
387 |
+
$v_supported_attributes
|
388 |
+
= array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
|
389 |
+
,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
|
390 |
+
,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
|
391 |
+
,PCLZIP_ATT_FILE_MTIME => 'optional'
|
392 |
+
,PCLZIP_ATT_FILE_CONTENT => 'optional'
|
393 |
+
,PCLZIP_ATT_FILE_COMMENT => 'optional'
|
394 |
+
);
|
395 |
+
foreach ($v_att_list as $v_entry) {
|
396 |
+
$v_result = $this->privFileDescrParseAtt($v_entry,
|
397 |
+
$v_filedescr_list[],
|
398 |
+
$v_options,
|
399 |
+
$v_supported_attributes);
|
400 |
+
if ($v_result != 1) {
|
401 |
+
return 0;
|
402 |
+
}
|
403 |
+
}
|
404 |
+
|
405 |
+
// ----- Expand the filelist (expand directories)
|
406 |
+
$v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
|
407 |
+
if ($v_result != 1) {
|
408 |
+
return 0;
|
409 |
+
}
|
410 |
+
|
411 |
+
// ----- Call the create fct
|
412 |
+
$v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
|
413 |
+
if ($v_result != 1) {
|
414 |
+
return 0;
|
415 |
+
}
|
416 |
+
|
417 |
+
// ----- Return
|
418 |
+
return $p_result_list;
|
419 |
+
}
|
420 |
+
// --------------------------------------------------------------------------------
|
421 |
+
|
422 |
+
// --------------------------------------------------------------------------------
|
423 |
+
// Function :
|
424 |
+
// add($p_filelist, $p_add_dir="", $p_remove_dir="")
|
425 |
+
// add($p_filelist, $p_option, $p_option_value, ...)
|
426 |
+
// Description :
|
427 |
+
// This method supports two synopsis. The first one is historical.
|
428 |
+
// This methods add the list of files in an existing archive.
|
429 |
+
// If a file with the same name already exists, it is added at the end of the
|
430 |
+
// archive, the first one is still present.
|
431 |
+
// If the archive does not exist, it is created.
|
432 |
+
// Parameters :
|
433 |
+
// $p_filelist : An array containing file or directory names, or
|
434 |
+
// a string containing one filename or one directory name, or
|
435 |
+
// a string containing a list of filenames and/or directory
|
436 |
+
// names separated by spaces.
|
437 |
+
// $p_add_dir : A path to add before the real path of the archived file,
|
438 |
+
// in order to have it memorized in the archive.
|
439 |
+
// $p_remove_dir : A path to remove from the real path of the file to archive,
|
440 |
+
// in order to have a shorter path memorized in the archive.
|
441 |
+
// When $p_add_dir and $p_remove_dir are set, $p_remove_dir
|
442 |
+
// is removed first, before $p_add_dir is added.
|
443 |
+
// Options :
|
444 |
+
// PCLZIP_OPT_ADD_PATH :
|
445 |
+
// PCLZIP_OPT_REMOVE_PATH :
|
446 |
+
// PCLZIP_OPT_REMOVE_ALL_PATH :
|
447 |
+
// PCLZIP_OPT_COMMENT :
|
448 |
+
// PCLZIP_OPT_ADD_COMMENT :
|
449 |
+
// PCLZIP_OPT_PREPEND_COMMENT :
|
450 |
+
// PCLZIP_CB_PRE_ADD :
|
451 |
+
// PCLZIP_CB_POST_ADD :
|
452 |
+
// Return Values :
|
453 |
+
// 0 on failure,
|
454 |
+
// The list of the added files, with a status of the add action.
|
455 |
+
// (see PclZip::listContent() for list entry format)
|
456 |
+
// --------------------------------------------------------------------------------
|
457 |
+
function add($p_filelist)
|
458 |
+
{
|
459 |
+
$v_result=1;
|
460 |
+
|
461 |
+
// ----- Reset the error handler
|
462 |
+
$this->privErrorReset();
|
463 |
+
|
464 |
+
// ----- Set default values
|
465 |
+
$v_options = array();
|
466 |
+
$v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
|
467 |
+
|
468 |
+
// ----- Look for variable options arguments
|
469 |
+
$v_size = func_num_args();
|
470 |
+
|
471 |
+
// ----- Look for arguments
|
472 |
+
if ($v_size > 1) {
|
473 |
+
// ----- Get the arguments
|
474 |
+
$v_arg_list = func_get_args();
|
475 |
+
|
476 |
+
// ----- Remove form the options list the first argument
|
477 |
+
array_shift($v_arg_list);
|
478 |
+
$v_size--;
|
479 |
+
|
480 |
+
// ----- Look for first arg
|
481 |
+
if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
|
482 |
+
|
483 |
+
// ----- Parse the options
|
484 |
+
$v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
|
485 |
+
array (PCLZIP_OPT_REMOVE_PATH => 'optional',
|
486 |
+
PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
|
487 |
+
PCLZIP_OPT_ADD_PATH => 'optional',
|
488 |
+
PCLZIP_CB_PRE_ADD => 'optional',
|
489 |
+
PCLZIP_CB_POST_ADD => 'optional',
|
490 |
+
PCLZIP_OPT_NO_COMPRESSION => 'optional',
|
491 |
+
PCLZIP_OPT_COMMENT => 'optional',
|
492 |
+
PCLZIP_OPT_ADD_COMMENT => 'optional',
|
493 |
+
PCLZIP_OPT_PREPEND_COMMENT => 'optional',
|
494 |
+
PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
|
495 |
+
PCLZIP_OPT_TEMP_FILE_ON => 'optional',
|
496 |
+
PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
|
497 |
+
//, PCLZIP_OPT_CRYPT => 'optional'
|
498 |
+
));
|
499 |
+
if ($v_result != 1) {
|
500 |
+
return 0;
|
501 |
+
}
|
502 |
+
}
|
503 |
+
|
504 |
+
// ----- Look for 2 args
|
505 |
+
// Here we need to support the first historic synopsis of the
|
506 |
+
// method.
|
507 |
+
else {
|
508 |
+
|
509 |
+
// ----- Get the first argument
|
510 |
+
$v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
|
511 |
+
|
512 |
+
// ----- Look for the optional second argument
|
513 |
+
if ($v_size == 2) {
|
514 |
+
$v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
|
515 |
+
}
|
516 |
+
else if ($v_size > 2) {
|
517 |
+
// ----- Error log
|
518 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
|
519 |
+
|
520 |
+
// ----- Return
|
521 |
+
return 0;
|
522 |
+
}
|
523 |
+
}
|
524 |
+
}
|
525 |
+
|
526 |
+
// ----- Look for default option values
|
527 |
+
$this->privOptionDefaultThreshold($v_options);
|
528 |
+
|
529 |
+
// ----- Init
|
530 |
+
$v_string_list = array();
|
531 |
+
$v_att_list = array();
|
532 |
+
$v_filedescr_list = array();
|
533 |
+
$p_result_list = array();
|
534 |
+
|
535 |
+
// ----- Look if the $p_filelist is really an array
|
536 |
+
if (is_array($p_filelist)) {
|
537 |
+
|
538 |
+
// ----- Look if the first element is also an array
|
539 |
+
// This will mean that this is a file description entry
|
540 |
+
if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
|
541 |
+
$v_att_list = $p_filelist;
|
542 |
+
}
|
543 |
+
|
544 |
+
// ----- The list is a list of string names
|
545 |
+
else {
|
546 |
+
$v_string_list = $p_filelist;
|
547 |
+
}
|
548 |
+
}
|
549 |
+
|
550 |
+
// ----- Look if the $p_filelist is a string
|
551 |
+
else if (is_string($p_filelist)) {
|
552 |
+
// ----- Create a list from the string
|
553 |
+
$v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
|
554 |
+
}
|
555 |
+
|
556 |
+
// ----- Invalid variable type for $p_filelist
|
557 |
+
else {
|
558 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
|
559 |
+
return 0;
|
560 |
+
}
|
561 |
+
|
562 |
+
// ----- Reformat the string list
|
563 |
+
if (sizeof($v_string_list) != 0) {
|
564 |
+
foreach ($v_string_list as $v_string) {
|
565 |
+
$v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
|
566 |
+
}
|
567 |
+
}
|
568 |
+
|
569 |
+
// ----- For each file in the list check the attributes
|
570 |
+
$v_supported_attributes
|
571 |
+
= array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
|
572 |
+
,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
|
573 |
+
,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
|
574 |
+
,PCLZIP_ATT_FILE_MTIME => 'optional'
|
575 |
+
,PCLZIP_ATT_FILE_CONTENT => 'optional'
|
576 |
+
,PCLZIP_ATT_FILE_COMMENT => 'optional'
|
577 |
+
);
|
578 |
+
foreach ($v_att_list as $v_entry) {
|
579 |
+
$v_result = $this->privFileDescrParseAtt($v_entry,
|
580 |
+
$v_filedescr_list[],
|
581 |
+
$v_options,
|
582 |
+
$v_supported_attributes);
|
583 |
+
if ($v_result != 1) {
|
584 |
+
return 0;
|
585 |
+
}
|
586 |
+
}
|
587 |
+
|
588 |
+
// ----- Expand the filelist (expand directories)
|
589 |
+
$v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
|
590 |
+
if ($v_result != 1) {
|
591 |
+
return 0;
|
592 |
+
}
|
593 |
+
|
594 |
+
// ----- Call the create fct
|
595 |
+
$v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
|
596 |
+
if ($v_result != 1) {
|
597 |
+
return 0;
|
598 |
+
}
|
599 |
+
|
600 |
+
// ----- Return
|
601 |
+
return $p_result_list;
|
602 |
+
}
|
603 |
+
// --------------------------------------------------------------------------------
|
604 |
+
|
605 |
+
// --------------------------------------------------------------------------------
|
606 |
+
// Function : listContent()
|
607 |
+
// Description :
|
608 |
+
// This public method, gives the list of the files and directories, with their
|
609 |
+
// properties.
|
610 |
+
// The properties of each entries in the list are (used also in other functions) :
|
611 |
+
// filename : Name of the file. For a create or add action it is the filename
|
612 |
+
// given by the user. For an extract function it is the filename
|
613 |
+
// of the extracted file.
|
614 |
+
// stored_filename : Name of the file / directory stored in the archive.
|
615 |
+
// size : Size of the stored file.
|
616 |
+
// compressed_size : Size of the file's data compressed in the archive
|
617 |
+
// (without the headers overhead)
|
618 |
+
// mtime : Last known modification date of the file (UNIX timestamp)
|
619 |
+
// comment : Comment associated with the file
|
620 |
+
// folder : true | false
|
621 |
+
// index : index of the file in the archive
|
622 |
+
// status : status of the action (depending of the action) :
|
623 |
+
// Values are :
|
624 |
+
// ok : OK !
|
625 |
+
// filtered : the file / dir is not extracted (filtered by user)
|
626 |
+
// already_a_directory : the file can not be extracted because a
|
627 |
+
// directory with the same name already exists
|
628 |
+
// write_protected : the file can not be extracted because a file
|
629 |
+
// with the same name already exists and is
|
630 |
+
// write protected
|
631 |
+
// newer_exist : the file was not extracted because a newer file exists
|
632 |
+
// path_creation_fail : the file is not extracted because the folder
|
633 |
+
// does not exist and can not be created
|
634 |
+
// write_error : the file was not extracted because there was a
|
635 |
+
// error while writing the file
|
636 |
+
// read_error : the file was not extracted because there was a error
|
637 |
+
// while reading the file
|
638 |
+
// invalid_header : the file was not extracted because of an archive
|
639 |
+
// format error (bad file header)
|
640 |
+
// Note that each time a method can continue operating when there
|
641 |
+
// is an action error on a file, the error is only logged in the file status.
|
642 |
+
// Return Values :
|
643 |
+
// 0 on an unrecoverable failure,
|
644 |
+
// The list of the files in the archive.
|
645 |
+
// --------------------------------------------------------------------------------
|
646 |
+
function listContent()
|
647 |
+
{
|
648 |
+
$v_result=1;
|
649 |
+
|
650 |
+
// ----- Reset the error handler
|
651 |
+
$this->privErrorReset();
|
652 |
+
|
653 |
+
// ----- Check archive
|
654 |
+
if (!$this->privCheckFormat()) {
|
655 |
+
return(0);
|
656 |
+
}
|
657 |
+
|
658 |
+
// ----- Call the extracting fct
|
659 |
+
$p_list = array();
|
660 |
+
if (($v_result = $this->privList($p_list)) != 1)
|
661 |
+
{
|
662 |
+
unset($p_list);
|
663 |
+
return(0);
|
664 |
+
}
|
665 |
+
|
666 |
+
// ----- Return
|
667 |
+
return $p_list;
|
668 |
+
}
|
669 |
+
// --------------------------------------------------------------------------------
|
670 |
+
|
671 |
+
// --------------------------------------------------------------------------------
|
672 |
+
// Function :
|
673 |
+
// extract($p_path="./", $p_remove_path="")
|
674 |
+
// extract([$p_option, $p_option_value, ...])
|
675 |
+
// Description :
|
676 |
+
// This method supports two synopsis. The first one is historical.
|
677 |
+
// This method extract all the files / directories from the archive to the
|
678 |
+
// folder indicated in $p_path.
|
679 |
+
// If you want to ignore the 'root' part of path of the memorized files
|
680 |
+
// you can indicate this in the optional $p_remove_path parameter.
|
681 |
+
// By default, if a newer file with the same name already exists, the
|
682 |
+
// file is not extracted.
|
683 |
+
//
|
684 |
+
// If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
|
685 |
+
// are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
|
686 |
+
// at the end of the path value of PCLZIP_OPT_PATH.
|
687 |
+
// Parameters :
|
688 |
+
// $p_path : Path where the files and directories are to be extracted
|
689 |
+
// $p_remove_path : First part ('root' part) of the memorized path
|
690 |
+
// (if any similar) to remove while extracting.
|
691 |
+
// Options :
|
692 |
+
// PCLZIP_OPT_PATH :
|
693 |
+
// PCLZIP_OPT_ADD_PATH :
|
694 |
+
// PCLZIP_OPT_REMOVE_PATH :
|
695 |
+
// PCLZIP_OPT_REMOVE_ALL_PATH :
|
696 |
+
// PCLZIP_CB_PRE_EXTRACT :
|
697 |
+
// PCLZIP_CB_POST_EXTRACT :
|
698 |
+
// Return Values :
|
699 |
+
// 0 or a negative value on failure,
|
700 |
+
// The list of the extracted files, with a status of the action.
|
701 |
+
// (see PclZip::listContent() for list entry format)
|
702 |
+
// --------------------------------------------------------------------------------
|
703 |
+
function extract()
|
704 |
+
{
|
705 |
+
$v_result=1;
|
706 |
+
|
707 |
+
// ----- Reset the error handler
|
708 |
+
$this->privErrorReset();
|
709 |
+
|
710 |
+
// ----- Check archive
|
711 |
+
if (!$this->privCheckFormat()) {
|
712 |
+
return(0);
|
713 |
+
}
|
714 |
+
|
715 |
+
// ----- Set default values
|
716 |
+
$v_options = array();
|
717 |
+
// $v_path = "./";
|
718 |
+
$v_path = '';
|
719 |
+
$v_remove_path = "";
|
720 |
+
$v_remove_all_path = false;
|
721 |
+
|
722 |
+
// ----- Look for variable options arguments
|
723 |
+
$v_size = func_num_args();
|
724 |
+
|
725 |
+
// ----- Default values for option
|
726 |
+
$v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
|
727 |
+
|
728 |
+
// ----- Look for arguments
|
729 |
+
if ($v_size > 0) {
|
730 |
+
// ----- Get the arguments
|
731 |
+
$v_arg_list = func_get_args();
|
732 |
+
|
733 |
+
// ----- Look for first arg
|
734 |
+
if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
|
735 |
+
|
736 |
+
// ----- Parse the options
|
737 |
+
$v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
|
738 |
+
array (PCLZIP_OPT_PATH => 'optional',
|
739 |
+
PCLZIP_OPT_REMOVE_PATH => 'optional',
|
740 |
+
PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
|
741 |
+
PCLZIP_OPT_ADD_PATH => 'optional',
|
742 |
+
PCLZIP_CB_PRE_EXTRACT => 'optional',
|
743 |
+
PCLZIP_CB_POST_EXTRACT => 'optional',
|
744 |
+
PCLZIP_OPT_SET_CHMOD => 'optional',
|
745 |
+
PCLZIP_OPT_BY_NAME => 'optional',
|
746 |
+
PCLZIP_OPT_BY_EREG => 'optional',
|
747 |
+
PCLZIP_OPT_BY_PREG => 'optional',
|
748 |
+
PCLZIP_OPT_BY_INDEX => 'optional',
|
749 |
+
PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
|
750 |
+
PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
|
751 |
+
PCLZIP_OPT_REPLACE_NEWER => 'optional'
|
752 |
+
,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
|
753 |
+
,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
|
754 |
+
PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
|
755 |
+
PCLZIP_OPT_TEMP_FILE_ON => 'optional',
|
756 |
+
PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
|
757 |
+
));
|
758 |
+
if ($v_result != 1) {
|
759 |
+
return 0;
|
760 |
+
}
|
761 |
+
|
762 |
+
// ----- Set the arguments
|
763 |
+
if (isset($v_options[PCLZIP_OPT_PATH])) {
|
764 |
+
$v_path = $v_options[PCLZIP_OPT_PATH];
|
765 |
+
}
|
766 |
+
if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
|
767 |
+
$v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
|
768 |
+
}
|
769 |
+
if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
|
770 |
+
$v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
|
771 |
+
}
|
772 |
+
if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
|
773 |
+
// ----- Check for '/' in last path char
|
774 |
+
if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
|
775 |
+
$v_path .= '/';
|
776 |
+
}
|
777 |
+
$v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
|
778 |
+
}
|
779 |
+
}
|
780 |
+
|
781 |
+
// ----- Look for 2 args
|
782 |
+
// Here we need to support the first historic synopsis of the
|
783 |
+
// method.
|
784 |
+
else {
|
785 |
+
|
786 |
+
// ----- Get the first argument
|
787 |
+
$v_path = $v_arg_list[0];
|
788 |
+
|
789 |
+
// ----- Look for the optional second argument
|
790 |
+
if ($v_size == 2) {
|
791 |
+
$v_remove_path = $v_arg_list[1];
|
792 |
+
}
|
793 |
+
else if ($v_size > 2) {
|
794 |
+
// ----- Error log
|
795 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
|
796 |
+
|
797 |
+
// ----- Return
|
798 |
+
return 0;
|
799 |
+
}
|
800 |
+
}
|
801 |
+
}
|
802 |
+
|
803 |
+
// ----- Look for default option values
|
804 |
+
$this->privOptionDefaultThreshold($v_options);
|
805 |
+
|
806 |
+
// ----- Trace
|
807 |
+
|
808 |
+
// ----- Call the extracting fct
|
809 |
+
$p_list = array();
|
810 |
+
$v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
|
811 |
+
$v_remove_all_path, $v_options);
|
812 |
+
if ($v_result < 1) {
|
813 |
+
unset($p_list);
|
814 |
+
return(0);
|
815 |
+
}
|
816 |
+
|
817 |
+
// ----- Return
|
818 |
+
return $p_list;
|
819 |
+
}
|
820 |
+
// --------------------------------------------------------------------------------
|
821 |
+
|
822 |
+
|
823 |
+
// --------------------------------------------------------------------------------
|
824 |
+
// Function :
|
825 |
+
// extractByIndex($p_index, $p_path="./", $p_remove_path="")
|
826 |
+
// extractByIndex($p_index, [$p_option, $p_option_value, ...])
|
827 |
+
// Description :
|
828 |
+
// This method supports two synopsis. The first one is historical.
|
829 |
+
// This method is doing a partial extract of the archive.
|
830 |
+
// The extracted files or folders are identified by their index in the
|
831 |
+
// archive (from 0 to n).
|
832 |
+
// Note that if the index identify a folder, only the folder entry is
|
833 |
+
// extracted, not all the files included in the archive.
|
834 |
+
// Parameters :
|
835 |
+
// $p_index : A single index (integer) or a string of indexes of files to
|
836 |
+
// extract. The form of the string is "0,4-6,8-12" with only numbers
|
837 |
+
// and '-' for range or ',' to separate ranges. No spaces or ';'
|
838 |
+
// are allowed.
|
839 |
+
// $p_path : Path where the files and directories are to be extracted
|
840 |
+
// $p_remove_path : First part ('root' part) of the memorized path
|
841 |
+
// (if any similar) to remove while extracting.
|
842 |
+
// Options :
|
843 |
+
// PCLZIP_OPT_PATH :
|
844 |
+
// PCLZIP_OPT_ADD_PATH :
|
845 |
+
// PCLZIP_OPT_REMOVE_PATH :
|
846 |
+
// PCLZIP_OPT_REMOVE_ALL_PATH :
|
847 |
+
// PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
|
848 |
+
// not as files.
|
849 |
+
// The resulting content is in a new field 'content' in the file
|
850 |
+
// structure.
|
851 |
+
// This option must be used alone (any other options are ignored).
|
852 |
+
// PCLZIP_CB_PRE_EXTRACT :
|
853 |
+
// PCLZIP_CB_POST_EXTRACT :
|
854 |
+
// Return Values :
|
855 |
+
// 0 on failure,
|
856 |
+
// The list of the extracted files, with a status of the action.
|
857 |
+
// (see PclZip::listContent() for list entry format)
|
858 |
+
// --------------------------------------------------------------------------------
|
859 |
+
//function extractByIndex($p_index, options...)
|
860 |
+
function extractByIndex($p_index)
|
861 |
+
{
|
862 |
+
$v_result=1;
|
863 |
+
|
864 |
+
// ----- Reset the error handler
|
865 |
+
$this->privErrorReset();
|
866 |
+
|
867 |
+
// ----- Check archive
|
868 |
+
if (!$this->privCheckFormat()) {
|
869 |
+
return(0);
|
870 |
+
}
|
871 |
+
|
872 |
+
// ----- Set default values
|
873 |
+
$v_options = array();
|
874 |
+
// $v_path = "./";
|
875 |
+
$v_path = '';
|
876 |
+
$v_remove_path = "";
|
877 |
+
$v_remove_all_path = false;
|
878 |
+
|
879 |
+
// ----- Look for variable options arguments
|
880 |
+
$v_size = func_num_args();
|
881 |
+
|
882 |
+
// ----- Default values for option
|
883 |
+
$v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
|
884 |
+
|
885 |
+
// ----- Look for arguments
|
886 |
+
if ($v_size > 1) {
|
887 |
+
// ----- Get the arguments
|
888 |
+
$v_arg_list = func_get_args();
|
889 |
+
|
890 |
+
// ----- Remove form the options list the first argument
|
891 |
+
array_shift($v_arg_list);
|
892 |
+
$v_size--;
|
893 |
+
|
894 |
+
// ----- Look for first arg
|
895 |
+
if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
|
896 |
+
|
897 |
+
// ----- Parse the options
|
898 |
+
$v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
|
899 |
+
array (PCLZIP_OPT_PATH => 'optional',
|
900 |
+
PCLZIP_OPT_REMOVE_PATH => 'optional',
|
901 |
+
PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
|
902 |
+
PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
|
903 |
+
PCLZIP_OPT_ADD_PATH => 'optional',
|
904 |
+
PCLZIP_CB_PRE_EXTRACT => 'optional',
|
905 |
+
PCLZIP_CB_POST_EXTRACT => 'optional',
|
906 |
+
PCLZIP_OPT_SET_CHMOD => 'optional',
|
907 |
+
PCLZIP_OPT_REPLACE_NEWER => 'optional'
|
908 |
+
,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
|
909 |
+
,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
|
910 |
+
PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
|
911 |
+
PCLZIP_OPT_TEMP_FILE_ON => 'optional',
|
912 |
+
PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
|
913 |
+
));
|
914 |
+
if ($v_result != 1) {
|
915 |
+
return 0;
|
916 |
+
}
|
917 |
+
|
918 |
+
// ----- Set the arguments
|
919 |
+
if (isset($v_options[PCLZIP_OPT_PATH])) {
|
920 |
+
$v_path = $v_options[PCLZIP_OPT_PATH];
|
921 |
+
}
|
922 |
+
if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
|
923 |
+
$v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
|
924 |
+
}
|
925 |
+
if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
|
926 |
+
$v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
|
927 |
+
}
|
928 |
+
if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
|
929 |
+
// ----- Check for '/' in last path char
|
930 |
+
if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
|
931 |
+
$v_path .= '/';
|
932 |
+
}
|
933 |
+
$v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
|
934 |
+
}
|
935 |
+
if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
|
936 |
+
$v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
|
937 |
+
}
|
938 |
+
else {
|
939 |
+
}
|
940 |
+
}
|
941 |
+
|
942 |
+
// ----- Look for 2 args
|
943 |
+
// Here we need to support the first historic synopsis of the
|
944 |
+
// method.
|
945 |
+
else {
|
946 |
+
|
947 |
+
// ----- Get the first argument
|
948 |
+
$v_path = $v_arg_list[0];
|
949 |
+
|
950 |
+
// ----- Look for the optional second argument
|
951 |
+
if ($v_size == 2) {
|
952 |
+
$v_remove_path = $v_arg_list[1];
|
953 |
+
}
|
954 |
+
else if ($v_size > 2) {
|
955 |
+
// ----- Error log
|
956 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
|
957 |
+
|
958 |
+
// ----- Return
|
959 |
+
return 0;
|
960 |
+
}
|
961 |
+
}
|
962 |
+
}
|
963 |
+
|
964 |
+
// ----- Trace
|
965 |
+
|
966 |
+
// ----- Trick
|
967 |
+
// Here I want to reuse extractByRule(), so I need to parse the $p_index
|
968 |
+
// with privParseOptions()
|
969 |
+
$v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
|
970 |
+
$v_options_trick = array();
|
971 |
+
$v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
|
972 |
+
array (PCLZIP_OPT_BY_INDEX => 'optional' ));
|
973 |
+
if ($v_result != 1) {
|
974 |
+
return 0;
|
975 |
+
}
|
976 |
+
$v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
|
977 |
+
|
978 |
+
// ----- Look for default option values
|
979 |
+
$this->privOptionDefaultThreshold($v_options);
|
980 |
+
|
981 |
+
// ----- Call the extracting fct
|
982 |
+
if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
|
983 |
+
return(0);
|
984 |
+
}
|
985 |
+
|
986 |
+
// ----- Return
|
987 |
+
return $p_list;
|
988 |
+
}
|
989 |
+
// --------------------------------------------------------------------------------
|
990 |
+
|
991 |
+
// --------------------------------------------------------------------------------
|
992 |
+
// Function :
|
993 |
+
// delete([$p_option, $p_option_value, ...])
|
994 |
+
// Description :
|
995 |
+
// This method removes files from the archive.
|
996 |
+
// If no parameters are given, then all the archive is emptied.
|
997 |
+
// Parameters :
|
998 |
+
// None or optional arguments.
|
999 |
+
// Options :
|
1000 |
+
// PCLZIP_OPT_BY_INDEX :
|
1001 |
+
// PCLZIP_OPT_BY_NAME :
|
1002 |
+
// PCLZIP_OPT_BY_EREG :
|
1003 |
+
// PCLZIP_OPT_BY_PREG :
|
1004 |
+
// Return Values :
|
1005 |
+
// 0 on failure,
|
1006 |
+
// The list of the files which are still present in the archive.
|
1007 |
+
// (see PclZip::listContent() for list entry format)
|
1008 |
+
// --------------------------------------------------------------------------------
|
1009 |
+
function delete()
|
1010 |
+
{
|
1011 |
+
$v_result=1;
|
1012 |
+
|
1013 |
+
// ----- Reset the error handler
|
1014 |
+
$this->privErrorReset();
|
1015 |
+
|
1016 |
+
// ----- Check archive
|
1017 |
+
if (!$this->privCheckFormat()) {
|
1018 |
+
return(0);
|
1019 |
+
}
|
1020 |
+
|
1021 |
+
// ----- Set default values
|
1022 |
+
$v_options = array();
|
1023 |
+
|
1024 |
+
// ----- Look for variable options arguments
|
1025 |
+
$v_size = func_num_args();
|
1026 |
+
|
1027 |
+
// ----- Look for arguments
|
1028 |
+
if ($v_size > 0) {
|
1029 |
+
// ----- Get the arguments
|
1030 |
+
$v_arg_list = func_get_args();
|
1031 |
+
|
1032 |
+
// ----- Parse the options
|
1033 |
+
$v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
|
1034 |
+
array (PCLZIP_OPT_BY_NAME => 'optional',
|
1035 |
+
PCLZIP_OPT_BY_EREG => 'optional',
|
1036 |
+
PCLZIP_OPT_BY_PREG => 'optional',
|
1037 |
+
PCLZIP_OPT_BY_INDEX => 'optional' ));
|
1038 |
+
if ($v_result != 1) {
|
1039 |
+
return 0;
|
1040 |
+
}
|
1041 |
+
}
|
1042 |
+
|
1043 |
+
// ----- Magic quotes trick
|
1044 |
+
$this->privDisableMagicQuotes();
|
1045 |
+
|
1046 |
+
// ----- Call the delete fct
|
1047 |
+
$v_list = array();
|
1048 |
+
if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
|
1049 |
+
$this->privSwapBackMagicQuotes();
|
1050 |
+
unset($v_list);
|
1051 |
+
return(0);
|
1052 |
+
}
|
1053 |
+
|
1054 |
+
// ----- Magic quotes trick
|
1055 |
+
$this->privSwapBackMagicQuotes();
|
1056 |
+
|
1057 |
+
// ----- Return
|
1058 |
+
return $v_list;
|
1059 |
+
}
|
1060 |
+
// --------------------------------------------------------------------------------
|
1061 |
+
|
1062 |
+
// --------------------------------------------------------------------------------
|
1063 |
+
// Function : deleteByIndex()
|
1064 |
+
// Description :
|
1065 |
+
// ***** Deprecated *****
|
1066 |
+
// delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
|
1067 |
+
// --------------------------------------------------------------------------------
|
1068 |
+
function deleteByIndex($p_index)
|
1069 |
+
{
|
1070 |
+
|
1071 |
+
$p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
|
1072 |
+
|
1073 |
+
// ----- Return
|
1074 |
+
return $p_list;
|
1075 |
+
}
|
1076 |
+
// --------------------------------------------------------------------------------
|
1077 |
+
|
1078 |
+
// --------------------------------------------------------------------------------
|
1079 |
+
// Function : properties()
|
1080 |
+
// Description :
|
1081 |
+
// This method gives the properties of the archive.
|
1082 |
+
// The properties are :
|
1083 |
+
// nb : Number of files in the archive
|
1084 |
+
// comment : Comment associated with the archive file
|
1085 |
+
// status : not_exist, ok
|
1086 |
+
// Parameters :
|
1087 |
+
// None
|
1088 |
+
// Return Values :
|
1089 |
+
// 0 on failure,
|
1090 |
+
// An array with the archive properties.
|
1091 |
+
// --------------------------------------------------------------------------------
|
1092 |
+
function properties()
|
1093 |
+
{
|
1094 |
+
|
1095 |
+
// ----- Reset the error handler
|
1096 |
+
$this->privErrorReset();
|
1097 |
+
|
1098 |
+
// ----- Magic quotes trick
|
1099 |
+
$this->privDisableMagicQuotes();
|
1100 |
+
|
1101 |
+
// ----- Check archive
|
1102 |
+
if (!$this->privCheckFormat()) {
|
1103 |
+
$this->privSwapBackMagicQuotes();
|
1104 |
+
return(0);
|
1105 |
+
}
|
1106 |
+
|
1107 |
+
// ----- Default properties
|
1108 |
+
$v_prop = array();
|
1109 |
+
$v_prop['comment'] = '';
|
1110 |
+
$v_prop['nb'] = 0;
|
1111 |
+
$v_prop['status'] = 'not_exist';
|
1112 |
+
|
1113 |
+
// ----- Look if file exists
|
1114 |
+
if (@is_file($this->zipname))
|
1115 |
+
{
|
1116 |
+
// ----- Open the zip file
|
1117 |
+
if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
|
1118 |
+
{
|
1119 |
+
$this->privSwapBackMagicQuotes();
|
1120 |
+
|
1121 |
+
// ----- Error log
|
1122 |
+
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
|
1123 |
+
|
1124 |
+
// ----- Return
|
1125 |
+
return 0;
|
1126 |
+
}
|
1127 |
+
|
1128 |
+
// ----- Read the central directory informations
|
1129 |
+
$v_central_dir = array();
|
1130 |
+
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
|
1131 |
+
{
|
1132 |
+
$this->privSwapBackMagicQuotes();
|
1133 |
+
return 0;
|
1134 |
+
}
|
1135 |
+
|
1136 |
+
// ----- Close the zip file
|
1137 |
+
$this->privCloseFd();
|
1138 |
+
|
1139 |
+
// ----- Set the user attributes
|
1140 |
+
$v_prop['comment'] = $v_central_dir['comment'];
|
1141 |
+
$v_prop['nb'] = $v_central_dir['entries'];
|
1142 |
+
$v_prop['status'] = 'ok';
|
1143 |
+
}
|
1144 |
+
|
1145 |
+
// ----- Magic quotes trick
|
1146 |
+
$this->privSwapBackMagicQuotes();
|
1147 |
+
|
1148 |
+
// ----- Return
|
1149 |
+
return $v_prop;
|
1150 |
+
}
|
1151 |
+
// --------------------------------------------------------------------------------
|
1152 |
+
|
1153 |
+
// --------------------------------------------------------------------------------
|
1154 |
+
// Function : duplicate()
|
1155 |
+
// Description :
|
1156 |
+
// This method creates an archive by copying the content of an other one. If
|
1157 |
+
// the archive already exist, it is replaced by the new one without any warning.
|
1158 |
+
// Parameters :
|
1159 |
+
// $p_archive : The filename of a valid archive, or
|
1160 |
+
// a valid PclZip object.
|
1161 |
+
// Return Values :
|
1162 |
+
// 1 on success.
|
1163 |
+
// 0 or a negative value on error (error code).
|
1164 |
+
// --------------------------------------------------------------------------------
|
1165 |
+
function duplicate($p_archive)
|
1166 |
+
{
|
1167 |
+
$v_result = 1;
|
1168 |
+
|
1169 |
+
// ----- Reset the error handler
|
1170 |
+
$this->privErrorReset();
|
1171 |
+
|
1172 |
+
// ----- Look if the $p_archive is a PclZip object
|
1173 |
+
if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
|
1174 |
+
{
|
1175 |
+
|
1176 |
+
// ----- Duplicate the archive
|
1177 |
+
$v_result = $this->privDuplicate($p_archive->zipname);
|
1178 |
+
}
|
1179 |
+
|
1180 |
+
// ----- Look if the $p_archive is a string (so a filename)
|
1181 |
+
else if (is_string($p_archive))
|
1182 |
+
{
|
1183 |
+
|
1184 |
+
// ----- Check that $p_archive is a valid zip file
|
1185 |
+
// TBC : Should also check the archive format
|
1186 |
+
if (!is_file($p_archive)) {
|
1187 |
+
// ----- Error log
|
1188 |
+
PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
|
1189 |
+
$v_result = PCLZIP_ERR_MISSING_FILE;
|
1190 |
+
}
|
1191 |
+
else {
|
1192 |
+
// ----- Duplicate the archive
|
1193 |
+
$v_result = $this->privDuplicate($p_archive);
|
1194 |
+
}
|
1195 |
+
}
|
1196 |
+
|
1197 |
+
// ----- Invalid variable
|
1198 |
+
else
|
1199 |
+
{
|
1200 |
+
// ----- Error log
|
1201 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
|
1202 |
+
$v_result = PCLZIP_ERR_INVALID_PARAMETER;
|
1203 |
+
}
|
1204 |
+
|
1205 |
+
// ----- Return
|
1206 |
+
return $v_result;
|
1207 |
+
}
|
1208 |
+
// --------------------------------------------------------------------------------
|
1209 |
+
|
1210 |
+
// --------------------------------------------------------------------------------
|
1211 |
+
// Function : merge()
|
1212 |
+
// Description :
|
1213 |
+
// This method merge the $p_archive_to_add archive at the end of the current
|
1214 |
+
// one ($this).
|
1215 |
+
// If the archive ($this) does not exist, the merge becomes a duplicate.
|
1216 |
+
// If the $p_archive_to_add archive does not exist, the merge is a success.
|
1217 |
+
// Parameters :
|
1218 |
+
// $p_archive_to_add : It can be directly the filename of a valid zip archive,
|
1219 |
+
// or a PclZip object archive.
|
1220 |
+
// Return Values :
|
1221 |
+
// 1 on success,
|
1222 |
+
// 0 or negative values on error (see below).
|
1223 |
+
// --------------------------------------------------------------------------------
|
1224 |
+
function merge($p_archive_to_add)
|
1225 |
+
{
|
1226 |
+
$v_result = 1;
|
1227 |
+
|
1228 |
+
// ----- Reset the error handler
|
1229 |
+
$this->privErrorReset();
|
1230 |
+
|
1231 |
+
// ----- Check archive
|
1232 |
+
if (!$this->privCheckFormat()) {
|
1233 |
+
return(0);
|
1234 |
+
}
|
1235 |
+
|
1236 |
+
// ----- Look if the $p_archive_to_add is a PclZip object
|
1237 |
+
if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
|
1238 |
+
{
|
1239 |
+
|
1240 |
+
// ----- Merge the archive
|
1241 |
+
$v_result = $this->privMerge($p_archive_to_add);
|
1242 |
+
}
|
1243 |
+
|
1244 |
+
// ----- Look if the $p_archive_to_add is a string (so a filename)
|
1245 |
+
else if (is_string($p_archive_to_add))
|
1246 |
+
{
|
1247 |
+
|
1248 |
+
// ----- Create a temporary archive
|
1249 |
+
$v_object_archive = new PclZip($p_archive_to_add);
|
1250 |
+
|
1251 |
+
// ----- Merge the archive
|
1252 |
+
$v_result = $this->privMerge($v_object_archive);
|
1253 |
+
}
|
1254 |
+
|
1255 |
+
// ----- Invalid variable
|
1256 |
+
else
|
1257 |
+
{
|
1258 |
+
// ----- Error log
|
1259 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
|
1260 |
+
$v_result = PCLZIP_ERR_INVALID_PARAMETER;
|
1261 |
+
}
|
1262 |
+
|
1263 |
+
// ----- Return
|
1264 |
+
return $v_result;
|
1265 |
+
}
|
1266 |
+
// --------------------------------------------------------------------------------
|
1267 |
+
|
1268 |
+
|
1269 |
+
|
1270 |
+
// --------------------------------------------------------------------------------
|
1271 |
+
// Function : errorCode()
|
1272 |
+
// Description :
|
1273 |
+
// Parameters :
|
1274 |
+
// --------------------------------------------------------------------------------
|
1275 |
+
function errorCode()
|
1276 |
+
{
|
1277 |
+
if (PCLZIP_ERROR_EXTERNAL == 1) {
|
1278 |
+
return(PclErrorCode());
|
1279 |
+
}
|
1280 |
+
else {
|
1281 |
+
return($this->error_code);
|
1282 |
+
}
|
1283 |
+
}
|
1284 |
+
// --------------------------------------------------------------------------------
|
1285 |
+
|
1286 |
+
// --------------------------------------------------------------------------------
|
1287 |
+
// Function : errorName()
|
1288 |
+
// Description :
|
1289 |
+
// Parameters :
|
1290 |
+
// --------------------------------------------------------------------------------
|
1291 |
+
function errorName($p_with_code=false)
|
1292 |
+
{
|
1293 |
+
$v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
|
1294 |
+
PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
|
1295 |
+
PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
|
1296 |
+
PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
|
1297 |
+
PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
|
1298 |
+
PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
|
1299 |
+
PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
|
1300 |
+
PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
|
1301 |
+
PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
|
1302 |
+
PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
|
1303 |
+
PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
|
1304 |
+
PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
|
1305 |
+
PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
|
1306 |
+
PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
|
1307 |
+
PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
|
1308 |
+
PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
|
1309 |
+
PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
|
1310 |
+
PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
|
1311 |
+
PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
|
1312 |
+
,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
|
1313 |
+
,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
|
1314 |
+
);
|
1315 |
+
|
1316 |
+
if (isset($v_name[$this->error_code])) {
|
1317 |
+
$v_value = $v_name[$this->error_code];
|
1318 |
+
}
|
1319 |
+
else {
|
1320 |
+
$v_value = 'NoName';
|
1321 |
+
}
|
1322 |
+
|
1323 |
+
if ($p_with_code) {
|
1324 |
+
return($v_value.' ('.$this->error_code.')');
|
1325 |
+
}
|
1326 |
+
else {
|
1327 |
+
return($v_value);
|
1328 |
+
}
|
1329 |
+
}
|
1330 |
+
// --------------------------------------------------------------------------------
|
1331 |
+
|
1332 |
+
// --------------------------------------------------------------------------------
|
1333 |
+
// Function : errorInfo()
|
1334 |
+
// Description :
|
1335 |
+
// Parameters :
|
1336 |
+
// --------------------------------------------------------------------------------
|
1337 |
+
function errorInfo($p_full=false)
|
1338 |
+
{
|
1339 |
+
if (PCLZIP_ERROR_EXTERNAL == 1) {
|
1340 |
+
return(PclErrorString());
|
1341 |
+
}
|
1342 |
+
else {
|
1343 |
+
if ($p_full) {
|
1344 |
+
return($this->errorName(true)." : ".$this->error_string);
|
1345 |
+
}
|
1346 |
+
else {
|
1347 |
+
return($this->error_string." [code ".$this->error_code."]");
|
1348 |
+
}
|
1349 |
+
}
|
1350 |
+
}
|
1351 |
+
// --------------------------------------------------------------------------------
|
1352 |
+
|
1353 |
+
|
1354 |
+
// --------------------------------------------------------------------------------
|
1355 |
+
// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
|
1356 |
+
// ***** *****
|
1357 |
+
// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****
|
1358 |
+
// --------------------------------------------------------------------------------
|
1359 |
+
|
1360 |
+
|
1361 |
+
|
1362 |
+
// --------------------------------------------------------------------------------
|
1363 |
+
// Function : privCheckFormat()
|
1364 |
+
// Description :
|
1365 |
+
// This method check that the archive exists and is a valid zip archive.
|
1366 |
+
// Several level of check exists. (futur)
|
1367 |
+
// Parameters :
|
1368 |
+
// $p_level : Level of check. Default 0.
|
1369 |
+
// 0 : Check the first bytes (magic codes) (default value))
|
1370 |
+
// 1 : 0 + Check the central directory (futur)
|
1371 |
+
// 2 : 1 + Check each file header (futur)
|
1372 |
+
// Return Values :
|
1373 |
+
// true on success,
|
1374 |
+
// false on error, the error code is set.
|
1375 |
+
// --------------------------------------------------------------------------------
|
1376 |
+
function privCheckFormat($p_level=0)
|
1377 |
+
{
|
1378 |
+
$v_result = true;
|
1379 |
+
|
1380 |
+
// ----- Reset the file system cache
|
1381 |
+
clearstatcache();
|
1382 |
+
|
1383 |
+
// ----- Reset the error handler
|
1384 |
+
$this->privErrorReset();
|
1385 |
+
|
1386 |
+
// ----- Look if the file exits
|
1387 |
+
if (!is_file($this->zipname)) {
|
1388 |
+
// ----- Error log
|
1389 |
+
PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
|
1390 |
+
return(false);
|
1391 |
+
}
|
1392 |
+
|
1393 |
+
// ----- Check that the file is readeable
|
1394 |
+
if (!is_readable($this->zipname)) {
|
1395 |
+
// ----- Error log
|
1396 |
+
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
|
1397 |
+
return(false);
|
1398 |
+
}
|
1399 |
+
|
1400 |
+
// ----- Check the magic code
|
1401 |
+
// TBC
|
1402 |
+
|
1403 |
+
// ----- Check the central header
|
1404 |
+
// TBC
|
1405 |
+
|
1406 |
+
// ----- Check each file header
|
1407 |
+
// TBC
|
1408 |
+
|
1409 |
+
// ----- Return
|
1410 |
+
return $v_result;
|
1411 |
+
}
|
1412 |
+
// --------------------------------------------------------------------------------
|
1413 |
+
|
1414 |
+
// --------------------------------------------------------------------------------
|
1415 |
+
// Function : privParseOptions()
|
1416 |
+
// Description :
|
1417 |
+
// This internal methods reads the variable list of arguments ($p_options_list,
|
1418 |
+
// $p_size) and generate an array with the options and values ($v_result_list).
|
1419 |
+
// $v_requested_options contains the options that can be present and those that
|
1420 |
+
// must be present.
|
1421 |
+
// $v_requested_options is an array, with the option value as key, and 'optional',
|
1422 |
+
// or 'mandatory' as value.
|
1423 |
+
// Parameters :
|
1424 |
+
// See above.
|
1425 |
+
// Return Values :
|
1426 |
+
// 1 on success.
|
1427 |
+
// 0 on failure.
|
1428 |
+
// --------------------------------------------------------------------------------
|
1429 |
+
function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
|
1430 |
+
{
|
1431 |
+
$v_result=1;
|
1432 |
+
|
1433 |
+
// ----- Read the options
|
1434 |
+
$i=0;
|
1435 |
+
while ($i<$p_size) {
|
1436 |
+
|
1437 |
+
// ----- Check if the option is supported
|
1438 |
+
if (!isset($v_requested_options[$p_options_list[$i]])) {
|
1439 |
+
// ----- Error log
|
1440 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
|
1441 |
+
|
1442 |
+
// ----- Return
|
1443 |
+
return PclZip::errorCode();
|
1444 |
+
}
|
1445 |
+
|
1446 |
+
// ----- Look for next option
|
1447 |
+
switch ($p_options_list[$i]) {
|
1448 |
+
// ----- Look for options that request a path value
|
1449 |
+
case PCLZIP_OPT_PATH :
|
1450 |
+
case PCLZIP_OPT_REMOVE_PATH :
|
1451 |
+
case PCLZIP_OPT_ADD_PATH :
|
1452 |
+
// ----- Check the number of parameters
|
1453 |
+
if (($i+1) >= $p_size) {
|
1454 |
+
// ----- Error log
|
1455 |
+
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
|
1456 |
+
|
1457 |
+
// ----- Return
|
1458 |
+
return PclZip::errorCode();
|
1459 |
+
}
|
1460 |
+
|
1461 |
+
// ----- Get the value
|
1462 |
+
$v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
|
1463 |
+
$i++;
|
1464 |
+
break;
|
1465 |
+
|
1466 |
+
case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
|
1467 |
+
// ----- Check the number of parameters
|
1468 |
+
if (($i+1) >= $p_size) {
|
1469 |
+
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
|
1470 |
+
return PclZip::errorCode();
|
1471 |
+
}
|
1472 |
+
|
1473 |
+
// ----- Check for incompatible options
|
1474 |
+
if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
|
1475 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
|
1476 |
+
return PclZip::errorCode();
|
1477 |
+
}
|
1478 |
+
|
1479 |
+
// ----- Check the value
|
1480 |
+
$v_value = $p_options_list[$i+1];
|
1481 |
+
if ((!is_integer($v_value)) || ($v_value<0)) {
|
1482 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");
|
1483 |
+
return PclZip::errorCode();
|
1484 |
+
}
|
1485 |
+
|
1486 |
+
// ----- Get the value (and convert it in bytes)
|
1487 |
+
$v_result_list[$p_options_list[$i]] = $v_value*1048576;
|
1488 |
+
$i++;
|
1489 |
+
break;
|
1490 |
+
|
1491 |
+
case PCLZIP_OPT_TEMP_FILE_ON :
|
1492 |
+
// ----- Check for incompatible options
|
1493 |
+
if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
|
1494 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
|
1495 |
+
return PclZip::errorCode();
|
1496 |
+
}
|
1497 |
+
|
1498 |
+
$v_result_list[$p_options_list[$i]] = true;
|
1499 |
+
break;
|
1500 |
+
|
1501 |
+
case PCLZIP_OPT_TEMP_FILE_OFF :
|
1502 |
+
// ----- Check for incompatible options
|
1503 |
+
if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
|
1504 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
|
1505 |
+
return PclZip::errorCode();
|
1506 |
+
}
|
1507 |
+
// ----- Check for incompatible options
|
1508 |
+
if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
|
1509 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
|
1510 |
+
return PclZip::errorCode();
|
1511 |
+
}
|
1512 |
+
|
1513 |
+
$v_result_list[$p_options_list[$i]] = true;
|
1514 |
+
break;
|
1515 |
+
|
1516 |
+
case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
|
1517 |
+
// ----- Check the number of parameters
|
1518 |
+
if (($i+1) >= $p_size) {
|
1519 |
+
// ----- Error log
|
1520 |
+
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
|
1521 |
+
|
1522 |
+
// ----- Return
|
1523 |
+
return PclZip::errorCode();
|
1524 |
+
}
|
1525 |
+
|
1526 |
+
// ----- Get the value
|
1527 |
+
if ( is_string($p_options_list[$i+1])
|
1528 |
+
&& ($p_options_list[$i+1] != '')) {
|
1529 |
+
$v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
|
1530 |
+
$i++;
|
1531 |
+
}
|
1532 |
+
else {
|
1533 |
+
}
|
1534 |
+
break;
|
1535 |
+
|
1536 |
+
// ----- Look for options that request an array of string for value
|
1537 |
+
case PCLZIP_OPT_BY_NAME :
|
1538 |
+
// ----- Check the number of parameters
|
1539 |
+
if (($i+1) >= $p_size) {
|
1540 |
+
// ----- Error log
|
1541 |
+
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
|
1542 |
+
|
1543 |
+
// ----- Return
|
1544 |
+
return PclZip::errorCode();
|
1545 |
+
}
|
1546 |
+
|
1547 |
+
// ----- Get the value
|
1548 |
+
if (is_string($p_options_list[$i+1])) {
|
1549 |
+
$v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
|
1550 |
+
}
|
1551 |
+
else if (is_array($p_options_list[$i+1])) {
|
1552 |
+
$v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
|
1553 |
+
}
|
1554 |
+
else {
|
1555 |
+
// ----- Error log
|
1556 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
|
1557 |
+
|
1558 |
+
// ----- Return
|
1559 |
+
return PclZip::errorCode();
|
1560 |
+
}
|
1561 |
+
$i++;
|
1562 |
+
break;
|
1563 |
+
|
1564 |
+
// ----- Look for options that request an EREG or PREG expression
|
1565 |
+
case PCLZIP_OPT_BY_EREG :
|
1566 |
+
// ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG
|
1567 |
+
// to PCLZIP_OPT_BY_PREG
|
1568 |
+
$p_options_list[$i] = PCLZIP_OPT_BY_PREG;
|
1569 |
+
case PCLZIP_OPT_BY_PREG :
|
1570 |
+
//case PCLZIP_OPT_CRYPT :
|
1571 |
+
// ----- Check the number of parameters
|
1572 |
+
if (($i+1) >= $p_size) {
|
1573 |
+
// ----- Error log
|
1574 |
+
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
|
1575 |
+
|
1576 |
+
// ----- Return
|
1577 |
+
return PclZip::errorCode();
|
1578 |
+
}
|
1579 |
+
|
1580 |
+
// ----- Get the value
|
1581 |
+
if (is_string($p_options_list[$i+1])) {
|
1582 |
+
$v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
|
1583 |
+
}
|
1584 |
+
else {
|
1585 |
+
// ----- Error log
|
1586 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
|
1587 |
+
|
1588 |
+
// ----- Return
|
1589 |
+
return PclZip::errorCode();
|
1590 |
+
}
|
1591 |
+
$i++;
|
1592 |
+
break;
|
1593 |
+
|
1594 |
+
// ----- Look for options that takes a string
|
1595 |
+
case PCLZIP_OPT_COMMENT :
|
1596 |
+
case PCLZIP_OPT_ADD_COMMENT :
|
1597 |
+
case PCLZIP_OPT_PREPEND_COMMENT :
|
1598 |
+
// ----- Check the number of parameters
|
1599 |
+
if (($i+1) >= $p_size) {
|
1600 |
+
// ----- Error log
|
1601 |
+
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
|
1602 |
+
"Missing parameter value for option '"
|
1603 |
+
.PclZipUtilOptionText($p_options_list[$i])
|
1604 |
+
."'");
|
1605 |
+
|
1606 |
+
// ----- Return
|
1607 |
+
return PclZip::errorCode();
|
1608 |
+
}
|
1609 |
+
|
1610 |
+
// ----- Get the value
|
1611 |
+
if (is_string($p_options_list[$i+1])) {
|
1612 |
+
$v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
|
1613 |
+
}
|
1614 |
+
else {
|
1615 |
+
// ----- Error log
|
1616 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
|
1617 |
+
"Wrong parameter value for option '"
|
1618 |
+
.PclZipUtilOptionText($p_options_list[$i])
|
1619 |
+
."'");
|
1620 |
+
|
1621 |
+
// ----- Return
|
1622 |
+
return PclZip::errorCode();
|
1623 |
+
}
|
1624 |
+
$i++;
|
1625 |
+
break;
|
1626 |
+
|
1627 |
+
// ----- Look for options that request an array of index
|
1628 |
+
case PCLZIP_OPT_BY_INDEX :
|
1629 |
+
// ----- Check the number of parameters
|
1630 |
+
if (($i+1) >= $p_size) {
|
1631 |
+
// ----- Error log
|
1632 |
+
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
|
1633 |
+
|
1634 |
+
// ----- Return
|
1635 |
+
return PclZip::errorCode();
|
1636 |
+
}
|
1637 |
+
|
1638 |
+
// ----- Get the value
|
1639 |
+
$v_work_list = array();
|
1640 |
+
if (is_string($p_options_list[$i+1])) {
|
1641 |
+
|
1642 |
+
// ----- Remove spaces
|
1643 |
+
$p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
|
1644 |
+
|
1645 |
+
// ----- Parse items
|
1646 |
+
$v_work_list = explode(",", $p_options_list[$i+1]);
|
1647 |
+
}
|
1648 |
+
else if (is_integer($p_options_list[$i+1])) {
|
1649 |
+
$v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
|
1650 |
+
}
|
1651 |
+
else if (is_array($p_options_list[$i+1])) {
|
1652 |
+
$v_work_list = $p_options_list[$i+1];
|
1653 |
+
}
|
1654 |
+
else {
|
1655 |
+
// ----- Error log
|
1656 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
|
1657 |
+
|
1658 |
+
// ----- Return
|
1659 |
+
return PclZip::errorCode();
|
1660 |
+
}
|
1661 |
+
|
1662 |
+
// ----- Reduce the index list
|
1663 |
+
// each index item in the list must be a couple with a start and
|
1664 |
+
// an end value : [0,3], [5-5], [8-10], ...
|
1665 |
+
// ----- Check the format of each item
|
1666 |
+
$v_sort_flag=false;
|
1667 |
+
$v_sort_value=0;
|
1668 |
+
for ($j=0; $j<sizeof($v_work_list); $j++) {
|
1669 |
+
// ----- Explode the item
|
1670 |
+
$v_item_list = explode("-", $v_work_list[$j]);
|
1671 |
+
$v_size_item_list = sizeof($v_item_list);
|
1672 |
+
|
1673 |
+
// ----- TBC : Here we might check that each item is a
|
1674 |
+
// real integer ...
|
1675 |
+
|
1676 |
+
// ----- Look for single value
|
1677 |
+
if ($v_size_item_list == 1) {
|
1678 |
+
// ----- Set the option value
|
1679 |
+
$v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
|
1680 |
+
$v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
|
1681 |
+
}
|
1682 |
+
elseif ($v_size_item_list == 2) {
|
1683 |
+
// ----- Set the option value
|
1684 |
+
$v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
|
1685 |
+
$v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
|
1686 |
+
}
|
1687 |
+
else {
|
1688 |
+
// ----- Error log
|
1689 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
|
1690 |
+
|
1691 |
+
// ----- Return
|
1692 |
+
return PclZip::errorCode();
|
1693 |
+
}
|
1694 |
+
|
1695 |
+
|
1696 |
+
// ----- Look for list sort
|
1697 |
+
if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
|
1698 |
+
$v_sort_flag=true;
|
1699 |
+
|
1700 |
+
// ----- TBC : An automatic sort should be writen ...
|
1701 |
+
// ----- Error log
|
1702 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
|
1703 |
+
|
1704 |
+
// ----- Return
|
1705 |
+
return PclZip::errorCode();
|
1706 |
+
}
|
1707 |
+
$v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
|
1708 |
+
}
|
1709 |
+
|
1710 |
+
// ----- Sort the items
|
1711 |
+
if ($v_sort_flag) {
|
1712 |
+
// TBC : To Be Completed
|
1713 |
+
}
|
1714 |
+
|
1715 |
+
// ----- Next option
|
1716 |
+
$i++;
|
1717 |
+
break;
|
1718 |
+
|
1719 |
+
// ----- Look for options that request no value
|
1720 |
+
case PCLZIP_OPT_REMOVE_ALL_PATH :
|
1721 |
+
case PCLZIP_OPT_EXTRACT_AS_STRING :
|
1722 |
+
case PCLZIP_OPT_NO_COMPRESSION :
|
1723 |
+
case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
|
1724 |
+
case PCLZIP_OPT_REPLACE_NEWER :
|
1725 |
+
case PCLZIP_OPT_STOP_ON_ERROR :
|
1726 |
+
$v_result_list[$p_options_list[$i]] = true;
|
1727 |
+
break;
|
1728 |
+
|
1729 |
+
// ----- Look for options that request an octal value
|
1730 |
+
case PCLZIP_OPT_SET_CHMOD :
|
1731 |
+
// ----- Check the number of parameters
|
1732 |
+
if (($i+1) >= $p_size) {
|
1733 |
+
// ----- Error log
|
1734 |
+
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
|
1735 |
+
|
1736 |
+
// ----- Return
|
1737 |
+
return PclZip::errorCode();
|
1738 |
+
}
|
1739 |
+
|
1740 |
+
// ----- Get the value
|
1741 |
+
$v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
|
1742 |
+
$i++;
|
1743 |
+
break;
|
1744 |
+
|
1745 |
+
// ----- Look for options that request a call-back
|
1746 |
+
case PCLZIP_CB_PRE_EXTRACT :
|
1747 |
+
case PCLZIP_CB_POST_EXTRACT :
|
1748 |
+
case PCLZIP_CB_PRE_ADD :
|
1749 |
+
case PCLZIP_CB_POST_ADD :
|
1750 |
+
/* for futur use
|
1751 |
+
case PCLZIP_CB_PRE_DELETE :
|
1752 |
+
case PCLZIP_CB_POST_DELETE :
|
1753 |
+
case PCLZIP_CB_PRE_LIST :
|
1754 |
+
case PCLZIP_CB_POST_LIST :
|
1755 |
+
*/
|
1756 |
+
// ----- Check the number of parameters
|
1757 |
+
if (($i+1) >= $p_size) {
|
1758 |
+
// ----- Error log
|
1759 |
+
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
|
1760 |
+
|
1761 |
+
// ----- Return
|
1762 |
+
return PclZip::errorCode();
|
1763 |
+
}
|
1764 |
+
|
1765 |
+
// ----- Get the value
|
1766 |
+
$v_function_name = $p_options_list[$i+1];
|
1767 |
+
|
1768 |
+
// ----- Check that the value is a valid existing function
|
1769 |
+
if (!function_exists($v_function_name)) {
|
1770 |
+
// ----- Error log
|
1771 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
|
1772 |
+
|
1773 |
+
// ----- Return
|
1774 |
+
return PclZip::errorCode();
|
1775 |
+
}
|
1776 |
+
|
1777 |
+
// ----- Set the attribute
|
1778 |
+
$v_result_list[$p_options_list[$i]] = $v_function_name;
|
1779 |
+
$i++;
|
1780 |
+
break;
|
1781 |
+
|
1782 |
+
default :
|
1783 |
+
// ----- Error log
|
1784 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
|
1785 |
+
"Unknown parameter '"
|
1786 |
+
.$p_options_list[$i]."'");
|
1787 |
+
|
1788 |
+
// ----- Return
|
1789 |
+
return PclZip::errorCode();
|
1790 |
+
}
|
1791 |
+
|
1792 |
+
// ----- Next options
|
1793 |
+
$i++;
|
1794 |
+
}
|
1795 |
+
|
1796 |
+
// ----- Look for mandatory options
|
1797 |
+
if ($v_requested_options !== false) {
|
1798 |
+
for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
|
1799 |
+
// ----- Look for mandatory option
|
1800 |
+
if ($v_requested_options[$key] == 'mandatory') {
|
1801 |
+
// ----- Look if present
|
1802 |
+
if (!isset($v_result_list[$key])) {
|
1803 |
+
// ----- Error log
|
1804 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
|
1805 |
+
|
1806 |
+
// ----- Return
|
1807 |
+
return PclZip::errorCode();
|
1808 |
+
}
|
1809 |
+
}
|
1810 |
+
}
|
1811 |
+
}
|
1812 |
+
|
1813 |
+
// ----- Look for default values
|
1814 |
+
if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
|
1815 |
+
|
1816 |
+
}
|
1817 |
+
|
1818 |
+
// ----- Return
|
1819 |
+
return $v_result;
|
1820 |
+
}
|
1821 |
+
// --------------------------------------------------------------------------------
|
1822 |
+
|
1823 |
+
// --------------------------------------------------------------------------------
|
1824 |
+
// Function : privOptionDefaultThreshold()
|
1825 |
+
// Description :
|
1826 |
+
// Parameters :
|
1827 |
+
// Return Values :
|
1828 |
+
// --------------------------------------------------------------------------------
|
1829 |
+
function privOptionDefaultThreshold(&$p_options)
|
1830 |
+
{
|
1831 |
+
$v_result=1;
|
1832 |
+
|
1833 |
+
if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
|
1834 |
+
|| isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
|
1835 |
+
return $v_result;
|
1836 |
+
}
|
1837 |
+
|
1838 |
+
// ----- Get 'memory_limit' configuration value
|
1839 |
+
$v_memory_limit = ini_get('memory_limit');
|
1840 |
+
$v_memory_limit = trim($v_memory_limit);
|
1841 |
+
$last = strtolower(substr($v_memory_limit, -1));
|
1842 |
+
|
1843 |
+
if($last == 'g')
|
1844 |
+
//$v_memory_limit = $v_memory_limit*1024*1024*1024;
|
1845 |
+
$v_memory_limit = $v_memory_limit*1073741824;
|
1846 |
+
if($last == 'm')
|
1847 |
+
//$v_memory_limit = $v_memory_limit*1024*1024;
|
1848 |
+
$v_memory_limit = $v_memory_limit*1048576;
|
1849 |
+
if($last == 'k')
|
1850 |
+
$v_memory_limit = $v_memory_limit*1024;
|
1851 |
+
|
1852 |
+
$p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);
|
1853 |
+
|
1854 |
+
|
1855 |
+
// ----- Sanity check : No threshold if value lower than 1M
|
1856 |
+
if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
|
1857 |
+
unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
|
1858 |
+
}
|
1859 |
+
|
1860 |
+
// ----- Return
|
1861 |
+
return $v_result;
|
1862 |
+
}
|
1863 |
+
// --------------------------------------------------------------------------------
|
1864 |
+
|
1865 |
+
// --------------------------------------------------------------------------------
|
1866 |
+
// Function : privFileDescrParseAtt()
|
1867 |
+
// Description :
|
1868 |
+
// Parameters :
|
1869 |
+
// Return Values :
|
1870 |
+
// 1 on success.
|
1871 |
+
// 0 on failure.
|
1872 |
+
// --------------------------------------------------------------------------------
|
1873 |
+
function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
|
1874 |
+
{
|
1875 |
+
$v_result=1;
|
1876 |
+
|
1877 |
+
// ----- For each file in the list check the attributes
|
1878 |
+
foreach ($p_file_list as $v_key => $v_value) {
|
1879 |
+
|
1880 |
+
// ----- Check if the option is supported
|
1881 |
+
if (!isset($v_requested_options[$v_key])) {
|
1882 |
+
// ----- Error log
|
1883 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
|
1884 |
+
|
1885 |
+
// ----- Return
|
1886 |
+
return PclZip::errorCode();
|
1887 |
+
}
|
1888 |
+
|
1889 |
+
// ----- Look for attribute
|
1890 |
+
switch ($v_key) {
|
1891 |
+
case PCLZIP_ATT_FILE_NAME :
|
1892 |
+
if (!is_string($v_value)) {
|
1893 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
|
1894 |
+
return PclZip::errorCode();
|
1895 |
+
}
|
1896 |
+
|
1897 |
+
$p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
|
1898 |
+
|
1899 |
+
if ($p_filedescr['filename'] == '') {
|
1900 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
|
1901 |
+
return PclZip::errorCode();
|
1902 |
+
}
|
1903 |
+
|
1904 |
+
break;
|
1905 |
+
|
1906 |
+
case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
|
1907 |
+
if (!is_string($v_value)) {
|
1908 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
|
1909 |
+
return PclZip::errorCode();
|
1910 |
+
}
|
1911 |
+
|
1912 |
+
$p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
|
1913 |
+
|
1914 |
+
if ($p_filedescr['new_short_name'] == '') {
|
1915 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
|
1916 |
+
return PclZip::errorCode();
|
1917 |
+
}
|
1918 |
+
break;
|
1919 |
+
|
1920 |
+
case PCLZIP_ATT_FILE_NEW_FULL_NAME :
|
1921 |
+
if (!is_string($v_value)) {
|
1922 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
|
1923 |
+
return PclZip::errorCode();
|
1924 |
+
}
|
1925 |
+
|
1926 |
+
$p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
|
1927 |
+
|
1928 |
+
if ($p_filedescr['new_full_name'] == '') {
|
1929 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
|
1930 |
+
return PclZip::errorCode();
|
1931 |
+
}
|
1932 |
+
break;
|
1933 |
+
|
1934 |
+
// ----- Look for options that takes a string
|
1935 |
+
case PCLZIP_ATT_FILE_COMMENT :
|
1936 |
+
if (!is_string($v_value)) {
|
1937 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
|
1938 |
+
return PclZip::errorCode();
|
1939 |
+
}
|
1940 |
+
|
1941 |
+
$p_filedescr['comment'] = $v_value;
|
1942 |
+
break;
|
1943 |
+
|
1944 |
+
case PCLZIP_ATT_FILE_MTIME :
|
1945 |
+
if (!is_integer($v_value)) {
|
1946 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
|
1947 |
+
return PclZip::errorCode();
|
1948 |
+
}
|
1949 |
+
|
1950 |
+
$p_filedescr['mtime'] = $v_value;
|
1951 |
+
break;
|
1952 |
+
|
1953 |
+
case PCLZIP_ATT_FILE_CONTENT :
|
1954 |
+
$p_filedescr['content'] = $v_value;
|
1955 |
+
break;
|
1956 |
+
|
1957 |
+
default :
|
1958 |
+
// ----- Error log
|
1959 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
|
1960 |
+
"Unknown parameter '".$v_key."'");
|
1961 |
+
|
1962 |
+
// ----- Return
|
1963 |
+
return PclZip::errorCode();
|
1964 |
+
}
|
1965 |
+
|
1966 |
+
// ----- Look for mandatory options
|
1967 |
+
if ($v_requested_options !== false) {
|
1968 |
+
for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
|
1969 |
+
// ----- Look for mandatory option
|
1970 |
+
if ($v_requested_options[$key] == 'mandatory') {
|
1971 |
+
// ----- Look if present
|
1972 |
+
if (!isset($p_file_list[$key])) {
|
1973 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
|
1974 |
+
return PclZip::errorCode();
|
1975 |
+
}
|
1976 |
+
}
|
1977 |
+
}
|
1978 |
+
}
|
1979 |
+
|
1980 |
+
// end foreach
|
1981 |
+
}
|
1982 |
+
|
1983 |
+
// ----- Return
|
1984 |
+
return $v_result;
|
1985 |
+
}
|
1986 |
+
// --------------------------------------------------------------------------------
|
1987 |
+
|
1988 |
+
// --------------------------------------------------------------------------------
|
1989 |
+
// Function : privFileDescrExpand()
|
1990 |
+
// Description :
|
1991 |
+
// This method look for each item of the list to see if its a file, a folder
|
1992 |
+
// or a string to be added as file. For any other type of files (link, other)
|
1993 |
+
// just ignore the item.
|
1994 |
+
// Then prepare the information that will be stored for that file.
|
1995 |
+
// When its a folder, expand the folder with all the files that are in that
|
1996 |
+
// folder (recursively).
|
1997 |
+
// Parameters :
|
1998 |
+
// Return Values :
|
1999 |
+
// 1 on success.
|
2000 |
+
// 0 on failure.
|
2001 |
+
// --------------------------------------------------------------------------------
|
2002 |
+
function privFileDescrExpand(&$p_filedescr_list, &$p_options)
|
2003 |
+
{
|
2004 |
+
$v_result=1;
|
2005 |
+
|
2006 |
+
// ----- Create a result list
|
2007 |
+
$v_result_list = array();
|
2008 |
+
|
2009 |
+
// ----- Look each entry
|
2010 |
+
for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
|
2011 |
+
|
2012 |
+
// ----- Get filedescr
|
2013 |
+
$v_descr = $p_filedescr_list[$i];
|
2014 |
+
|
2015 |
+
// ----- Reduce the filename
|
2016 |
+
$v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
|
2017 |
+
$v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
|
2018 |
+
|
2019 |
+
// ----- Look for real file or folder
|
2020 |
+
if (file_exists($v_descr['filename'])) {
|
2021 |
+
if (@is_file($v_descr['filename'])) {
|
2022 |
+
$v_descr['type'] = 'file';
|
2023 |
+
}
|
2024 |
+
else if (@is_dir($v_descr['filename'])) {
|
2025 |
+
$v_descr['type'] = 'folder';
|
2026 |
+
}
|
2027 |
+
else if (@is_link($v_descr['filename'])) {
|
2028 |
+
// skip
|
2029 |
+
continue;
|
2030 |
+
}
|
2031 |
+
else {
|
2032 |
+
// skip
|
2033 |
+
continue;
|
2034 |
+
}
|
2035 |
+
}
|
2036 |
+
|
2037 |
+
// ----- Look for string added as file
|
2038 |
+
else if (isset($v_descr['content'])) {
|
2039 |
+
$v_descr['type'] = 'virtual_file';
|
2040 |
+
}
|
2041 |
+
|
2042 |
+
// ----- Missing file
|
2043 |
+
else {
|
2044 |
+
// ----- Error log
|
2045 |
+
PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");
|
2046 |
+
|
2047 |
+
// ----- Return
|
2048 |
+
return PclZip::errorCode();
|
2049 |
+
}
|
2050 |
+
|
2051 |
+
// ----- Calculate the stored filename
|
2052 |
+
$this->privCalculateStoredFilename($v_descr, $p_options);
|
2053 |
+
|
2054 |
+
// ----- Add the descriptor in result list
|
2055 |
+
$v_result_list[sizeof($v_result_list)] = $v_descr;
|
2056 |
+
|
2057 |
+
// ----- Look for folder
|
2058 |
+
if ($v_descr['type'] == 'folder') {
|
2059 |
+
// ----- List of items in folder
|
2060 |
+
$v_dirlist_descr = array();
|
2061 |
+
$v_dirlist_nb = 0;
|
2062 |
+
if ($v_folder_handler = @opendir($v_descr['filename'])) {
|
2063 |
+
while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
|
2064 |
+
|
2065 |
+
// ----- Skip '.' and '..'
|
2066 |
+
if (($v_item_handler == '.') || ($v_item_handler == '..')) {
|
2067 |
+
continue;
|
2068 |
+
}
|
2069 |
+
|
2070 |
+
// ----- Compose the full filename
|
2071 |
+
$v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
|
2072 |
+
|
2073 |
+
// ----- Look for different stored filename
|
2074 |
+
// Because the name of the folder was changed, the name of the
|
2075 |
+
// files/sub-folders also change
|
2076 |
+
if (($v_descr['stored_filename'] != $v_descr['filename'])
|
2077 |
+
&& (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
|
2078 |
+
if ($v_descr['stored_filename'] != '') {
|
2079 |
+
$v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
|
2080 |
+
}
|
2081 |
+
else {
|
2082 |
+
$v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
|
2083 |
+
}
|
2084 |
+
}
|
2085 |
+
|
2086 |
+
$v_dirlist_nb++;
|
2087 |
+
}
|
2088 |
+
|
2089 |
+
@closedir($v_folder_handler);
|
2090 |
+
}
|
2091 |
+
else {
|
2092 |
+
// TBC : unable to open folder in read mode
|
2093 |
+
}
|
2094 |
+
|
2095 |
+
// ----- Expand each element of the list
|
2096 |
+
if ($v_dirlist_nb != 0) {
|
2097 |
+
// ----- Expand
|
2098 |
+
if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
|
2099 |
+
return $v_result;
|
2100 |
+
}
|
2101 |
+
|
2102 |
+
// ----- Concat the resulting list
|
2103 |
+
$v_result_list = array_merge($v_result_list, $v_dirlist_descr);
|
2104 |
+
}
|
2105 |
+
else {
|
2106 |
+
}
|
2107 |
+
|
2108 |
+
// ----- Free local array
|
2109 |
+
unset($v_dirlist_descr);
|
2110 |
+
}
|
2111 |
+
}
|
2112 |
+
|
2113 |
+
// ----- Get the result list
|
2114 |
+
$p_filedescr_list = $v_result_list;
|
2115 |
+
|
2116 |
+
// ----- Return
|
2117 |
+
return $v_result;
|
2118 |
+
}
|
2119 |
+
// --------------------------------------------------------------------------------
|
2120 |
+
|
2121 |
+
// --------------------------------------------------------------------------------
|
2122 |
+
// Function : privCreate()
|
2123 |
+
// Description :
|
2124 |
+
// Parameters :
|
2125 |
+
// Return Values :
|
2126 |
+
// --------------------------------------------------------------------------------
|
2127 |
+
function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
|
2128 |
+
{
|
2129 |
+
$v_result=1;
|
2130 |
+
$v_list_detail = array();
|
2131 |
+
|
2132 |
+
// ----- Magic quotes trick
|
2133 |
+
$this->privDisableMagicQuotes();
|
2134 |
+
|
2135 |
+
// ----- Open the file in write mode
|
2136 |
+
if (($v_result = $this->privOpenFd('wb')) != 1)
|
2137 |
+
{
|
2138 |
+
// ----- Return
|
2139 |
+
return $v_result;
|
2140 |
+
}
|
2141 |
+
|
2142 |
+
// ----- Add the list of files
|
2143 |
+
$v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
|
2144 |
+
|
2145 |
+
// ----- Close
|
2146 |
+
$this->privCloseFd();
|
2147 |
+
|
2148 |
+
// ----- Magic quotes trick
|
2149 |
+
$this->privSwapBackMagicQuotes();
|
2150 |
+
|
2151 |
+
// ----- Return
|
2152 |
+
return $v_result;
|
2153 |
+
}
|
2154 |
+
// --------------------------------------------------------------------------------
|
2155 |
+
|
2156 |
+
// --------------------------------------------------------------------------------
|
2157 |
+
// Function : privAdd()
|
2158 |
+
// Description :
|
2159 |
+
// Parameters :
|
2160 |
+
// Return Values :
|
2161 |
+
// --------------------------------------------------------------------------------
|
2162 |
+
function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
|
2163 |
+
{
|
2164 |
+
$v_result=1;
|
2165 |
+
$v_list_detail = array();
|
2166 |
+
|
2167 |
+
// ----- Look if the archive exists or is empty
|
2168 |
+
if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
|
2169 |
+
{
|
2170 |
+
|
2171 |
+
// ----- Do a create
|
2172 |
+
$v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
|
2173 |
+
|
2174 |
+
// ----- Return
|
2175 |
+
return $v_result;
|
2176 |
+
}
|
2177 |
+
// ----- Magic quotes trick
|
2178 |
+
$this->privDisableMagicQuotes();
|
2179 |
+
|
2180 |
+
// ----- Open the zip file
|
2181 |
+
if (($v_result=$this->privOpenFd('rb')) != 1)
|
2182 |
+
{
|
2183 |
+
// ----- Magic quotes trick
|
2184 |
+
$this->privSwapBackMagicQuotes();
|
2185 |
+
|
2186 |
+
// ----- Return
|
2187 |
+
return $v_result;
|
2188 |
+
}
|
2189 |
+
|
2190 |
+
// ----- Read the central directory informations
|
2191 |
+
$v_central_dir = array();
|
2192 |
+
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
|
2193 |
+
{
|
2194 |
+
$this->privCloseFd();
|
2195 |
+
$this->privSwapBackMagicQuotes();
|
2196 |
+
return $v_result;
|
2197 |
+
}
|
2198 |
+
|
2199 |
+
// ----- Go to beginning of File
|
2200 |
+
@rewind($this->zip_fd);
|
2201 |
+
|
2202 |
+
// ----- Creates a temporay file
|
2203 |
+
$v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
|
2204 |
+
|
2205 |
+
// ----- Open the temporary file in write mode
|
2206 |
+
if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
|
2207 |
+
{
|
2208 |
+
$this->privCloseFd();
|
2209 |
+
$this->privSwapBackMagicQuotes();
|
2210 |
+
|
2211 |
+
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
|
2212 |
+
|
2213 |
+
// ----- Return
|
2214 |
+
return PclZip::errorCode();
|
2215 |
+
}
|
2216 |
+
|
2217 |
+
// ----- Copy the files from the archive to the temporary file
|
2218 |
+
// TBC : Here I should better append the file and go back to erase the central dir
|
2219 |
+
$v_size = $v_central_dir['offset'];
|
2220 |
+
while ($v_size != 0)
|
2221 |
+
{
|
2222 |
+
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
|
2223 |
+
$v_buffer = fread($this->zip_fd, $v_read_size);
|
2224 |
+
@fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
|
2225 |
+
$v_size -= $v_read_size;
|
2226 |
+
}
|
2227 |
+
|
2228 |
+
// ----- Swap the file descriptor
|
2229 |
+
// Here is a trick : I swap the temporary fd with the zip fd, in order to use
|
2230 |
+
// the following methods on the temporary fil and not the real archive
|
2231 |
+
$v_swap = $this->zip_fd;
|
2232 |
+
$this->zip_fd = $v_zip_temp_fd;
|
2233 |
+
$v_zip_temp_fd = $v_swap;
|
2234 |
+
|
2235 |
+
// ----- Add the files
|
2236 |
+
$v_header_list = array();
|
2237 |
+
if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
|
2238 |
+
{
|
2239 |
+
fclose($v_zip_temp_fd);
|
2240 |
+
$this->privCloseFd();
|
2241 |
+
@unlink($v_zip_temp_name);
|
2242 |
+
$this->privSwapBackMagicQuotes();
|
2243 |
+
|
2244 |
+
// ----- Return
|
2245 |
+
return $v_result;
|
2246 |
+
}
|
2247 |
+
|
2248 |
+
// ----- Store the offset of the central dir
|
2249 |
+
$v_offset = @ftell($this->zip_fd);
|
2250 |
+
|
2251 |
+
// ----- Copy the block of file headers from the old archive
|
2252 |
+
$v_size = $v_central_dir['size'];
|
2253 |
+
while ($v_size != 0)
|
2254 |
+
{
|
2255 |
+
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
|
2256 |
+
$v_buffer = @fread($v_zip_temp_fd, $v_read_size);
|
2257 |
+
@fwrite($this->zip_fd, $v_buffer, $v_read_size);
|
2258 |
+
$v_size -= $v_read_size;
|
2259 |
+
}
|
2260 |
+
|
2261 |
+
// ----- Create the Central Dir files header
|
2262 |
+
for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
|
2263 |
+
{
|
2264 |
+
// ----- Create the file header
|
2265 |
+
if ($v_header_list[$i]['status'] == 'ok') {
|
2266 |
+
if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
|
2267 |
+
fclose($v_zip_temp_fd);
|
2268 |
+
$this->privCloseFd();
|
2269 |
+
@unlink($v_zip_temp_name);
|
2270 |
+
$this->privSwapBackMagicQuotes();
|
2271 |
+
|
2272 |
+
// ----- Return
|
2273 |
+
return $v_result;
|
2274 |
+
}
|
2275 |
+
$v_count++;
|
2276 |
+
}
|
2277 |
+
|
2278 |
+
// ----- Transform the header to a 'usable' info
|
2279 |
+
$this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
|
2280 |
+
}
|
2281 |
+
|
2282 |
+
// ----- Zip file comment
|
2283 |
+
$v_comment = $v_central_dir['comment'];
|
2284 |
+
if (isset($p_options[PCLZIP_OPT_COMMENT])) {
|
2285 |
+
$v_comment = $p_options[PCLZIP_OPT_COMMENT];
|
2286 |
+
}
|
2287 |
+
if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
|
2288 |
+
$v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
|
2289 |
+
}
|
2290 |
+
if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
|
2291 |
+
$v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
|
2292 |
+
}
|
2293 |
+
|
2294 |
+
// ----- Calculate the size of the central header
|
2295 |
+
$v_size = @ftell($this->zip_fd)-$v_offset;
|
2296 |
+
|
2297 |
+
// ----- Create the central dir footer
|
2298 |
+
if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
|
2299 |
+
{
|
2300 |
+
// ----- Reset the file list
|
2301 |
+
unset($v_header_list);
|
2302 |
+
$this->privSwapBackMagicQuotes();
|
2303 |
+
|
2304 |
+
// ----- Return
|
2305 |
+
return $v_result;
|
2306 |
+
}
|
2307 |
+
|
2308 |
+
// ----- Swap back the file descriptor
|
2309 |
+
$v_swap = $this->zip_fd;
|
2310 |
+
$this->zip_fd = $v_zip_temp_fd;
|
2311 |
+
$v_zip_temp_fd = $v_swap;
|
2312 |
+
|
2313 |
+
// ----- Close
|
2314 |
+
$this->privCloseFd();
|
2315 |
+
|
2316 |
+
// ----- Close the temporary file
|
2317 |
+
@fclose($v_zip_temp_fd);
|
2318 |
+
|
2319 |
+
// ----- Magic quotes trick
|
2320 |
+
$this->privSwapBackMagicQuotes();
|
2321 |
+
|
2322 |
+
// ----- Delete the zip file
|
2323 |
+
// TBC : I should test the result ...
|
2324 |
+
@unlink($this->zipname);
|
2325 |
+
|
2326 |
+
// ----- Rename the temporary file
|
2327 |
+
// TBC : I should test the result ...
|
2328 |
+
//@rename($v_zip_temp_name, $this->zipname);
|
2329 |
+
PclZipUtilRename($v_zip_temp_name, $this->zipname);
|
2330 |
+
|
2331 |
+
// ----- Return
|
2332 |
+
return $v_result;
|
2333 |
+
}
|
2334 |
+
// --------------------------------------------------------------------------------
|
2335 |
+
|
2336 |
+
// --------------------------------------------------------------------------------
|
2337 |
+
// Function : privOpenFd()
|
2338 |
+
// Description :
|
2339 |
+
// Parameters :
|
2340 |
+
// --------------------------------------------------------------------------------
|
2341 |
+
function privOpenFd($p_mode)
|
2342 |
+
{
|
2343 |
+
$v_result=1;
|
2344 |
+
|
2345 |
+
// ----- Look if already open
|
2346 |
+
if ($this->zip_fd != 0)
|
2347 |
+
{
|
2348 |
+
// ----- Error log
|
2349 |
+
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
|
2350 |
+
|
2351 |
+
// ----- Return
|
2352 |
+
return PclZip::errorCode();
|
2353 |
+
}
|
2354 |
+
|
2355 |
+
// ----- Open the zip file
|
2356 |
+
if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
|
2357 |
+
{
|
2358 |
+
// ----- Error log
|
2359 |
+
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
|
2360 |
+
|
2361 |
+
// ----- Return
|
2362 |
+
return PclZip::errorCode();
|
2363 |
+
}
|
2364 |
+
|
2365 |
+
// ----- Return
|
2366 |
+
return $v_result;
|
2367 |
+
}
|
2368 |
+
// --------------------------------------------------------------------------------
|
2369 |
+
|
2370 |
+
// --------------------------------------------------------------------------------
|
2371 |
+
// Function : privCloseFd()
|
2372 |
+
// Description :
|
2373 |
+
// Parameters :
|
2374 |
+
// --------------------------------------------------------------------------------
|
2375 |
+
function privCloseFd()
|
2376 |
+
{
|
2377 |
+
$v_result=1;
|
2378 |
+
|
2379 |
+
if ($this->zip_fd != 0)
|
2380 |
+
@fclose($this->zip_fd);
|
2381 |
+
$this->zip_fd = 0;
|
2382 |
+
|
2383 |
+
// ----- Return
|
2384 |
+
return $v_result;
|
2385 |
+
}
|
2386 |
+
// --------------------------------------------------------------------------------
|
2387 |
+
|
2388 |
+
// --------------------------------------------------------------------------------
|
2389 |
+
// Function : privAddList()
|
2390 |
+
// Description :
|
2391 |
+
// $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
|
2392 |
+
// different from the real path of the file. This is usefull if you want to have PclTar
|
2393 |
+
// running in any directory, and memorize relative path from an other directory.
|
2394 |
+
// Parameters :
|
2395 |
+
// $p_list : An array containing the file or directory names to add in the tar
|
2396 |
+
// $p_result_list : list of added files with their properties (specially the status field)
|
2397 |
+
// $p_add_dir : Path to add in the filename path archived
|
2398 |
+
// $p_remove_dir : Path to remove in the filename path archived
|
2399 |
+
// Return Values :
|
2400 |
+
// --------------------------------------------------------------------------------
|
2401 |
+
// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
|
2402 |
+
function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
|
2403 |
+
{
|
2404 |
+
$v_result=1;
|
2405 |
+
|
2406 |
+
// ----- Add the files
|
2407 |
+
$v_header_list = array();
|
2408 |
+
if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
|
2409 |
+
{
|
2410 |
+
// ----- Return
|
2411 |
+
return $v_result;
|
2412 |
+
}
|
2413 |
+
|
2414 |
+
// ----- Store the offset of the central dir
|
2415 |
+
$v_offset = @ftell($this->zip_fd);
|
2416 |
+
|
2417 |
+
// ----- Create the Central Dir files header
|
2418 |
+
for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
|
2419 |
+
{
|
2420 |
+
// ----- Create the file header
|
2421 |
+
if ($v_header_list[$i]['status'] == 'ok') {
|
2422 |
+
if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
|
2423 |
+
// ----- Return
|
2424 |
+
return $v_result;
|
2425 |
+
}
|
2426 |
+
$v_count++;
|
2427 |
+
}
|
2428 |
+
|
2429 |
+
// ----- Transform the header to a 'usable' info
|
2430 |
+
$this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
|
2431 |
+
}
|
2432 |
+
|
2433 |
+
// ----- Zip file comment
|
2434 |
+
$v_comment = '';
|
2435 |
+
if (isset($p_options[PCLZIP_OPT_COMMENT])) {
|
2436 |
+
$v_comment = $p_options[PCLZIP_OPT_COMMENT];
|
2437 |
+
}
|
2438 |
+
|
2439 |
+
// ----- Calculate the size of the central header
|
2440 |
+
$v_size = @ftell($this->zip_fd)-$v_offset;
|
2441 |
+
|
2442 |
+
// ----- Create the central dir footer
|
2443 |
+
if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
|
2444 |
+
{
|
2445 |
+
// ----- Reset the file list
|
2446 |
+
unset($v_header_list);
|
2447 |
+
|
2448 |
+
// ----- Return
|
2449 |
+
return $v_result;
|
2450 |
+
}
|
2451 |
+
|
2452 |
+
// ----- Return
|
2453 |
+
return $v_result;
|
2454 |
+
}
|
2455 |
+
// --------------------------------------------------------------------------------
|
2456 |
+
|
2457 |
+
// --------------------------------------------------------------------------------
|
2458 |
+
// Function : privAddFileList()
|
2459 |
+
// Description :
|
2460 |
+
// Parameters :
|
2461 |
+
// $p_filedescr_list : An array containing the file description
|
2462 |
+
// or directory names to add in the zip
|
2463 |
+
// $p_result_list : list of added files with their properties (specially the status field)
|
2464 |
+
// Return Values :
|
2465 |
+
// --------------------------------------------------------------------------------
|
2466 |
+
function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
|
2467 |
+
{
|
2468 |
+
$v_result=1;
|
2469 |
+
$v_header = array();
|
2470 |
+
|
2471 |
+
// ----- Recuperate the current number of elt in list
|
2472 |
+
$v_nb = sizeof($p_result_list);
|
2473 |
+
|
2474 |
+
// ----- Loop on the files
|
2475 |
+
for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
|
2476 |
+
// ----- Format the filename
|
2477 |
+
$p_filedescr_list[$j]['filename']
|
2478 |
+
= PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
|
2479 |
+
|
2480 |
+
|
2481 |
+
// ----- Skip empty file names
|
2482 |
+
// TBC : Can this be possible ? not checked in DescrParseAtt ?
|
2483 |
+
if ($p_filedescr_list[$j]['filename'] == "") {
|
2484 |
+
continue;
|
2485 |
+
}
|
2486 |
+
|
2487 |
+
// ----- Check the filename
|
2488 |
+
if ( ($p_filedescr_list[$j]['type'] != 'virtual_file')
|
2489 |
+
&& (!file_exists($p_filedescr_list[$j]['filename']))) {
|
2490 |
+
PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist");
|
2491 |
+
return PclZip::errorCode();
|
2492 |
+
}
|
2493 |
+
|
2494 |
+
// ----- Look if it is a file or a dir with no all path remove option
|
2495 |
+
// or a dir with all its path removed
|
2496 |
+
// if ( (is_file($p_filedescr_list[$j]['filename']))
|
2497 |
+
// || ( is_dir($p_filedescr_list[$j]['filename'])
|
2498 |
+
if ( ($p_filedescr_list[$j]['type'] == 'file')
|
2499 |
+
|| ($p_filedescr_list[$j]['type'] == 'virtual_file')
|
2500 |
+
|| ( ($p_filedescr_list[$j]['type'] == 'folder')
|
2501 |
+
&& ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
|
2502 |
+
|| !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
|
2503 |
+
) {
|
2504 |
+
|
2505 |
+
// ----- Add the file
|
2506 |
+
$v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
|
2507 |
+
$p_options);
|
2508 |
+
if ($v_result != 1) {
|
2509 |
+
return $v_result;
|
2510 |
+
}
|
2511 |
+
|
2512 |
+
// ----- Store the file infos
|
2513 |
+
$p_result_list[$v_nb++] = $v_header;
|
2514 |
+
}
|
2515 |
+
}
|
2516 |
+
|
2517 |
+
// ----- Return
|
2518 |
+
return $v_result;
|
2519 |
+
}
|
2520 |
+
// --------------------------------------------------------------------------------
|
2521 |
+
|
2522 |
+
// --------------------------------------------------------------------------------
|
2523 |
+
// Function : privAddFile()
|
2524 |
+
// Description :
|
2525 |
+
// Parameters :
|
2526 |
+
// Return Values :
|
2527 |
+
// --------------------------------------------------------------------------------
|
2528 |
+
function privAddFile($p_filedescr, &$p_header, &$p_options)
|
2529 |
+
{
|
2530 |
+
$v_result=1;
|
2531 |
+
|
2532 |
+
// ----- Working variable
|
2533 |
+
$p_filename = $p_filedescr['filename'];
|
2534 |
+
|
2535 |
+
// TBC : Already done in the fileAtt check ... ?
|
2536 |
+
if ($p_filename == "") {
|
2537 |
+
// ----- Error log
|
2538 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
|
2539 |
+
|
2540 |
+
// ----- Return
|
2541 |
+
return PclZip::errorCode();
|
2542 |
+
}
|
2543 |
+
|
2544 |
+
// ----- Look for a stored different filename
|
2545 |
+
/* TBC : Removed
|
2546 |
+
if (isset($p_filedescr['stored_filename'])) {
|
2547 |
+
$v_stored_filename = $p_filedescr['stored_filename'];
|
2548 |
+
}
|
2549 |
+
else {
|
2550 |
+
$v_stored_filename = $p_filedescr['stored_filename'];
|
2551 |
+
}
|
2552 |
+
*/
|
2553 |
+
|
2554 |
+
// ----- Set the file properties
|
2555 |
+
clearstatcache();
|
2556 |
+
$p_header['version'] = 20;
|
2557 |
+
$p_header['version_extracted'] = 10;
|
2558 |
+
$p_header['flag'] = 0;
|
2559 |
+
$p_header['compression'] = 0;
|
2560 |
+
$p_header['crc'] = 0;
|
2561 |
+
$p_header['compressed_size'] = 0;
|
2562 |
+
$p_header['filename_len'] = strlen($p_filename);
|
2563 |
+
$p_header['extra_len'] = 0;
|
2564 |
+
$p_header['disk'] = 0;
|
2565 |
+
$p_header['internal'] = 0;
|
2566 |
+
$p_header['offset'] = 0;
|
2567 |
+
$p_header['filename'] = $p_filename;
|
2568 |
+
// TBC : Removed $p_header['stored_filename'] = $v_stored_filename;
|
2569 |
+
$p_header['stored_filename'] = $p_filedescr['stored_filename'];
|
2570 |
+
$p_header['extra'] = '';
|
2571 |
+
$p_header['status'] = 'ok';
|
2572 |
+
$p_header['index'] = -1;
|
2573 |
+
|
2574 |
+
// ----- Look for regular file
|
2575 |
+
if ($p_filedescr['type']=='file') {
|
2576 |
+
$p_header['external'] = 0x00000000;
|
2577 |
+
$p_header['size'] = filesize($p_filename);
|
2578 |
+
}
|
2579 |
+
|
2580 |
+
// ----- Look for regular folder
|
2581 |
+
else if ($p_filedescr['type']=='folder') {
|
2582 |
+
$p_header['external'] = 0x00000010;
|
2583 |
+
$p_header['mtime'] = filemtime($p_filename);
|
2584 |
+
$p_header['size'] = filesize($p_filename);
|
2585 |
+
}
|
2586 |
+
|
2587 |
+
// ----- Look for virtual file
|
2588 |
+
else if ($p_filedescr['type'] == 'virtual_file') {
|
2589 |
+
$p_header['external'] = 0x00000000;
|
2590 |
+
$p_header['size'] = strlen($p_filedescr['content']);
|
2591 |
+
}
|
2592 |
+
|
2593 |
+
|
2594 |
+
// ----- Look for filetime
|
2595 |
+
if (isset($p_filedescr['mtime'])) {
|
2596 |
+
$p_header['mtime'] = $p_filedescr['mtime'];
|
2597 |
+
}
|
2598 |
+
else if ($p_filedescr['type'] == 'virtual_file') {
|
2599 |
+
$p_header['mtime'] = time();
|
2600 |
+
}
|
2601 |
+
else {
|
2602 |
+
$p_header['mtime'] = filemtime($p_filename);
|
2603 |
+
}
|
2604 |
+
|
2605 |
+
// ------ Look for file comment
|
2606 |
+
if (isset($p_filedescr['comment'])) {
|
2607 |
+
$p_header['comment_len'] = strlen($p_filedescr['comment']);
|
2608 |
+
$p_header['comment'] = $p_filedescr['comment'];
|
2609 |
+
}
|
2610 |
+
else {
|
2611 |
+
$p_header['comment_len'] = 0;
|
2612 |
+
$p_header['comment'] = '';
|
2613 |
+
}
|
2614 |
+
|
2615 |
+
// ----- Look for pre-add callback
|
2616 |
+
if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
|
2617 |
+
|
2618 |
+
// ----- Generate a local information
|
2619 |
+
$v_local_header = array();
|
2620 |
+
$this->privConvertHeader2FileInfo($p_header, $v_local_header);
|
2621 |
+
|
2622 |
+
// ----- Call the callback
|
2623 |
+
// Here I do not use call_user_func() because I need to send a reference to the
|
2624 |
+
// header.
|
2625 |
+
// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
|
2626 |
+
$v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
|
2627 |
+
if ($v_result == 0) {
|
2628 |
+
// ----- Change the file status
|
2629 |
+
$p_header['status'] = "skipped";
|
2630 |
+
$v_result = 1;
|
2631 |
+
}
|
2632 |
+
|
2633 |
+
// ----- Update the informations
|
2634 |
+
// Only some fields can be modified
|
2635 |
+
if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
|
2636 |
+
$p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
|
2637 |
+
}
|
2638 |
+
}
|
2639 |
+
|
2640 |
+
// ----- Look for empty stored filename
|
2641 |
+
if ($p_header['stored_filename'] == "") {
|
2642 |
+
$p_header['status'] = "filtered";
|
2643 |
+
}
|
2644 |
+
|
2645 |
+
// ----- Check the path length
|
2646 |
+
if (strlen($p_header['stored_filename']) > 0xFF) {
|
2647 |
+
$p_header['status'] = 'filename_too_long';
|
2648 |
+
}
|
2649 |
+
|
2650 |
+
// ----- Look if no error, or file not skipped
|
2651 |
+
if ($p_header['status'] == 'ok') {
|
2652 |
+
|
2653 |
+
// ----- Look for a file
|
2654 |
+
if ($p_filedescr['type'] == 'file') {
|
2655 |
+
// ----- Look for using temporary file to zip
|
2656 |
+
if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
|
2657 |
+
&& (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
|
2658 |
+
|| (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
|
2659 |
+
&& ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
|
2660 |
+
$v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
|
2661 |
+
if ($v_result < PCLZIP_ERR_NO_ERROR) {
|
2662 |
+
return $v_result;
|
2663 |
+
}
|
2664 |
+
}
|
2665 |
+
|
2666 |
+
// ----- Use "in memory" zip algo
|
2667 |
+
else {
|
2668 |
+
|
2669 |
+
// ----- Open the source file
|
2670 |
+
if (($v_file = @fopen($p_filename, "rb")) == 0) {
|
2671 |
+
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
|
2672 |
+
return PclZip::errorCode();
|
2673 |
+
}
|
2674 |
+
|
2675 |
+
// ----- Read the file content
|
2676 |
+
$v_content = @fread($v_file, $p_header['size']);
|
2677 |
+
|
2678 |
+
// ----- Close the file
|
2679 |
+
@fclose($v_file);
|
2680 |
+
|
2681 |
+
// ----- Calculate the CRC
|
2682 |
+
$p_header['crc'] = @crc32($v_content);
|
2683 |
+
|
2684 |
+
// ----- Look for no compression
|
2685 |
+
if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
|
2686 |
+
// ----- Set header parameters
|
2687 |
+
$p_header['compressed_size'] = $p_header['size'];
|
2688 |
+
$p_header['compression'] = 0;
|
2689 |
+
}
|
2690 |
+
|
2691 |
+
// ----- Look for normal compression
|
2692 |
+
else {
|
2693 |
+
// ----- Compress the content
|
2694 |
+
$v_content = @gzdeflate($v_content);
|
2695 |
+
|
2696 |
+
// ----- Set header parameters
|
2697 |
+
$p_header['compressed_size'] = strlen($v_content);
|
2698 |
+
$p_header['compression'] = 8;
|
2699 |
+
}
|
2700 |
+
|
2701 |
+
// ----- Call the header generation
|
2702 |
+
if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
|
2703 |
+
@fclose($v_file);
|
2704 |
+
return $v_result;
|
2705 |
+
}
|
2706 |
+
|
2707 |
+
// ----- Write the compressed (or not) content
|
2708 |
+
@fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
|
2709 |
+
|
2710 |
+
}
|
2711 |
+
|
2712 |
+
}
|
2713 |
+
|
2714 |
+
// ----- Look for a virtual file (a file from string)
|
2715 |
+
else if ($p_filedescr['type'] == 'virtual_file') {
|
2716 |
+
|
2717 |
+
$v_content = $p_filedescr['content'];
|
2718 |
+
|
2719 |
+
// ----- Calculate the CRC
|
2720 |
+
$p_header['crc'] = @crc32($v_content);
|
2721 |
+
|
2722 |
+
// ----- Look for no compression
|
2723 |
+
if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
|
2724 |
+
// ----- Set header parameters
|
2725 |
+
$p_header['compressed_size'] = $p_header['size'];
|
2726 |
+
$p_header['compression'] = 0;
|
2727 |
+
}
|
2728 |
+
|
2729 |
+
// ----- Look for normal compression
|
2730 |
+
else {
|
2731 |
+
// ----- Compress the content
|
2732 |
+
$v_content = @gzdeflate($v_content);
|
2733 |
+
|
2734 |
+
// ----- Set header parameters
|
2735 |
+
$p_header['compressed_size'] = strlen($v_content);
|
2736 |
+
$p_header['compression'] = 8;
|
2737 |
+
}
|
2738 |
+
|
2739 |
+
// ----- Call the header generation
|
2740 |
+
if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
|
2741 |
+
@fclose($v_file);
|
2742 |
+
return $v_result;
|
2743 |
+
}
|
2744 |
+
|
2745 |
+
// ----- Write the compressed (or not) content
|
2746 |
+
@fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
|
2747 |
+
}
|
2748 |
+
|
2749 |
+
// ----- Look for a directory
|
2750 |
+
else if ($p_filedescr['type'] == 'folder') {
|
2751 |
+
// ----- Look for directory last '/'
|
2752 |
+
if (@substr($p_header['stored_filename'], -1) != '/') {
|
2753 |
+
$p_header['stored_filename'] .= '/';
|
2754 |
+
}
|
2755 |
+
|
2756 |
+
// ----- Set the file properties
|
2757 |
+
$p_header['size'] = 0;
|
2758 |
+
//$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked
|
2759 |
+
$p_header['external'] = 0x00000010; // Value for a folder : to be checked
|
2760 |
+
|
2761 |
+
// ----- Call the header generation
|
2762 |
+
if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
|
2763 |
+
{
|
2764 |
+
return $v_result;
|
2765 |
+
}
|
2766 |
+
}
|
2767 |
+
}
|
2768 |
+
|
2769 |
+
// ----- Look for post-add callback
|
2770 |
+
if (isset($p_options[PCLZIP_CB_POST_ADD])) {
|
2771 |
+
|
2772 |
+
// ----- Generate a local information
|
2773 |
+
$v_local_header = array();
|
2774 |
+
$this->privConvertHeader2FileInfo($p_header, $v_local_header);
|
2775 |
+
|
2776 |
+
// ----- Call the callback
|
2777 |
+
// Here I do not use call_user_func() because I need to send a reference to the
|
2778 |
+
// header.
|
2779 |
+
// eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
|
2780 |
+
$v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
|
2781 |
+
if ($v_result == 0) {
|
2782 |
+
// ----- Ignored
|
2783 |
+
$v_result = 1;
|
2784 |
+
}
|
2785 |
+
|
2786 |
+
// ----- Update the informations
|
2787 |
+
// Nothing can be modified
|
2788 |
+
}
|
2789 |
+
|
2790 |
+
// ----- Return
|
2791 |
+
return $v_result;
|
2792 |
+
}
|
2793 |
+
// --------------------------------------------------------------------------------
|
2794 |
+
|
2795 |
+
// --------------------------------------------------------------------------------
|
2796 |
+
// Function : privAddFileUsingTempFile()
|
2797 |
+
// Description :
|
2798 |
+
// Parameters :
|
2799 |
+
// Return Values :
|
2800 |
+
// --------------------------------------------------------------------------------
|
2801 |
+
function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
|
2802 |
+
{
|
2803 |
+
$v_result=PCLZIP_ERR_NO_ERROR;
|
2804 |
+
|
2805 |
+
// ----- Working variable
|
2806 |
+
$p_filename = $p_filedescr['filename'];
|
2807 |
+
|
2808 |
+
|
2809 |
+
// ----- Open the source file
|
2810 |
+
if (($v_file = @fopen($p_filename, "rb")) == 0) {
|
2811 |
+
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
|
2812 |
+
return PclZip::errorCode();
|
2813 |
+
}
|
2814 |
+
|
2815 |
+
// ----- Creates a compressed temporary file
|
2816 |
+
$v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
|
2817 |
+
if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
|
2818 |
+
fclose($v_file);
|
2819 |
+
PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
|
2820 |
+
return PclZip::errorCode();
|
2821 |
+
}
|
2822 |
+
|
2823 |
+
// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
|
2824 |
+
$v_size = filesize($p_filename);
|
2825 |
+
while ($v_size != 0) {
|
2826 |
+
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
|
2827 |
+
$v_buffer = @fread($v_file, $v_read_size);
|
2828 |
+
//$v_binary_data = pack('a'.$v_read_size, $v_buffer);
|
2829 |
+
@gzputs($v_file_compressed, $v_buffer, $v_read_size);
|
2830 |
+
$v_size -= $v_read_size;
|
2831 |
+
}
|
2832 |
+
|
2833 |
+
// ----- Close the file
|
2834 |
+
@fclose($v_file);
|
2835 |
+
@gzclose($v_file_compressed);
|
2836 |
+
|
2837 |
+
// ----- Check the minimum file size
|
2838 |
+
if (filesize($v_gzip_temp_name) < 18) {
|
2839 |
+
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
|
2840 |
+
return PclZip::errorCode();
|
2841 |
+
}
|
2842 |
+
|
2843 |
+
// ----- Extract the compressed attributes
|
2844 |
+
if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
|
2845 |
+
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
|
2846 |
+
return PclZip::errorCode();
|
2847 |
+
}
|
2848 |
+
|
2849 |
+
// ----- Read the gzip file header
|
2850 |
+
$v_binary_data = @fread($v_file_compressed, 10);
|
2851 |
+
$v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
|
2852 |
+
|
2853 |
+
// ----- Check some parameters
|
2854 |
+
$v_data_header['os'] = bin2hex($v_data_header['os']);
|
2855 |
+
|
2856 |
+
// ----- Read the gzip file footer
|
2857 |
+
@fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);
|
2858 |
+
$v_binary_data = @fread($v_file_compressed, 8);
|
2859 |
+
$v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
|
2860 |
+
|
2861 |
+
// ----- Set the attributes
|
2862 |
+
$p_header['compression'] = ord($v_data_header['cm']);
|
2863 |
+
//$p_header['mtime'] = $v_data_header['mtime'];
|
2864 |
+
$p_header['crc'] = $v_data_footer['crc'];
|
2865 |
+
$p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
|
2866 |
+
|
2867 |
+
// ----- Close the file
|
2868 |
+
@fclose($v_file_compressed);
|
2869 |
+
|
2870 |
+
// ----- Call the header generation
|
2871 |
+
if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
|
2872 |
+
return $v_result;
|
2873 |
+
}
|
2874 |
+
|
2875 |
+
// ----- Add the compressed data
|
2876 |
+
if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
|
2877 |
+
{
|
2878 |
+
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
|
2879 |
+
return PclZip::errorCode();
|
2880 |
+
}
|
2881 |
+
|
2882 |
+
// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
|
2883 |
+
fseek($v_file_compressed, 10);
|
2884 |
+
$v_size = $p_header['compressed_size'];
|
2885 |
+
while ($v_size != 0)
|
2886 |
+
{
|
2887 |
+
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
|
2888 |
+
$v_buffer = @fread($v_file_compressed, $v_read_size);
|
2889 |
+
//$v_binary_data = pack('a'.$v_read_size, $v_buffer);
|
2890 |
+
@fwrite($this->zip_fd, $v_buffer, $v_read_size);
|
2891 |
+
$v_size -= $v_read_size;
|
2892 |
+
}
|
2893 |
+
|
2894 |
+
// ----- Close the file
|
2895 |
+
@fclose($v_file_compressed);
|
2896 |
+
|
2897 |
+
// ----- Unlink the temporary file
|
2898 |
+
@unlink($v_gzip_temp_name);
|
2899 |
+
|
2900 |
+
// ----- Return
|
2901 |
+
return $v_result;
|
2902 |
+
}
|
2903 |
+
// --------------------------------------------------------------------------------
|
2904 |
+
|
2905 |
+
// --------------------------------------------------------------------------------
|
2906 |
+
// Function : privCalculateStoredFilename()
|
2907 |
+
// Description :
|
2908 |
+
// Based on file descriptor properties and global options, this method
|
2909 |
+
// calculate the filename that will be stored in the archive.
|
2910 |
+
// Parameters :
|
2911 |
+
// Return Values :
|
2912 |
+
// --------------------------------------------------------------------------------
|
2913 |
+
function privCalculateStoredFilename(&$p_filedescr, &$p_options)
|
2914 |
+
{
|
2915 |
+
$v_result=1;
|
2916 |
+
|
2917 |
+
// ----- Working variables
|
2918 |
+
$p_filename = $p_filedescr['filename'];
|
2919 |
+
if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
|
2920 |
+
$p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
|
2921 |
+
}
|
2922 |
+
else {
|
2923 |
+
$p_add_dir = '';
|
2924 |
+
}
|
2925 |
+
if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
|
2926 |
+
$p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
|
2927 |
+
}
|
2928 |
+
else {
|
2929 |
+
$p_remove_dir = '';
|
2930 |
+
}
|
2931 |
+
if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
|
2932 |
+
$p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
|
2933 |
+
}
|
2934 |
+
else {
|
2935 |
+
$p_remove_all_dir = 0;
|
2936 |
+
}
|
2937 |
+
|
2938 |
+
|
2939 |
+
// ----- Look for full name change
|
2940 |
+
if (isset($p_filedescr['new_full_name'])) {
|
2941 |
+
// ----- Remove drive letter if any
|
2942 |
+
$v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
|
2943 |
+
}
|
2944 |
+
|
2945 |
+
// ----- Look for path and/or short name change
|
2946 |
+
else {
|
2947 |
+
|
2948 |
+
// ----- Look for short name change
|
2949 |
+
// Its when we cahnge just the filename but not the path
|
2950 |
+
if (isset($p_filedescr['new_short_name'])) {
|
2951 |
+
$v_path_info = pathinfo($p_filename);
|
2952 |
+
$v_dir = '';
|
2953 |
+
if ($v_path_info['dirname'] != '') {
|
2954 |
+
$v_dir = $v_path_info['dirname'].'/';
|
2955 |
+
}
|
2956 |
+
$v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
|
2957 |
+
}
|
2958 |
+
else {
|
2959 |
+
// ----- Calculate the stored filename
|
2960 |
+
$v_stored_filename = $p_filename;
|
2961 |
+
}
|
2962 |
+
|
2963 |
+
// ----- Look for all path to remove
|
2964 |
+
if ($p_remove_all_dir) {
|
2965 |
+
$v_stored_filename = basename($p_filename);
|
2966 |
+
}
|
2967 |
+
// ----- Look for partial path remove
|
2968 |
+
else if ($p_remove_dir != "") {
|
2969 |
+
if (substr($p_remove_dir, -1) != '/')
|
2970 |
+
$p_remove_dir .= "/";
|
2971 |
+
|
2972 |
+
if ( (substr($p_filename, 0, 2) == "./")
|
2973 |
+
|| (substr($p_remove_dir, 0, 2) == "./")) {
|
2974 |
+
|
2975 |
+
if ( (substr($p_filename, 0, 2) == "./")
|
2976 |
+
&& (substr($p_remove_dir, 0, 2) != "./")) {
|
2977 |
+
$p_remove_dir = "./".$p_remove_dir;
|
2978 |
+
}
|
2979 |
+
if ( (substr($p_filename, 0, 2) != "./")
|
2980 |
+
&& (substr($p_remove_dir, 0, 2) == "./")) {
|
2981 |
+
$p_remove_dir = substr($p_remove_dir, 2);
|
2982 |
+
}
|
2983 |
+
}
|
2984 |
+
|
2985 |
+
$v_compare = PclZipUtilPathInclusion($p_remove_dir,
|
2986 |
+
$v_stored_filename);
|
2987 |
+
if ($v_compare > 0) {
|
2988 |
+
if ($v_compare == 2) {
|
2989 |
+
$v_stored_filename = "";
|
2990 |
+
}
|
2991 |
+
else {
|
2992 |
+
$v_stored_filename = substr($v_stored_filename,
|
2993 |
+
strlen($p_remove_dir));
|
2994 |
+
}
|
2995 |
+
}
|
2996 |
+
}
|
2997 |
+
|
2998 |
+
// ----- Remove drive letter if any
|
2999 |
+
$v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
|
3000 |
+
|
3001 |
+
// ----- Look for path to add
|
3002 |
+
if ($p_add_dir != "") {
|
3003 |
+
if (substr($p_add_dir, -1) == "/")
|
3004 |
+
$v_stored_filename = $p_add_dir.$v_stored_filename;
|
3005 |
+
else
|
3006 |
+
$v_stored_filename = $p_add_dir."/".$v_stored_filename;
|
3007 |
+
}
|
3008 |
+
}
|
3009 |
+
|
3010 |
+
// ----- Filename (reduce the path of stored name)
|
3011 |
+
$v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
|
3012 |
+
$p_filedescr['stored_filename'] = $v_stored_filename;
|
3013 |
+
|
3014 |
+
// ----- Return
|
3015 |
+
return $v_result;
|
3016 |
+
}
|
3017 |
+
// --------------------------------------------------------------------------------
|
3018 |
+
|
3019 |
+
// --------------------------------------------------------------------------------
|
3020 |
+
// Function : privWriteFileHeader()
|
3021 |
+
// Description :
|
3022 |
+
// Parameters :
|
3023 |
+
// Return Values :
|
3024 |
+
// --------------------------------------------------------------------------------
|
3025 |
+
function privWriteFileHeader(&$p_header)
|
3026 |
+
{
|
3027 |
+
$v_result=1;
|
3028 |
+
|
3029 |
+
// ----- Store the offset position of the file
|
3030 |
+
$p_header['offset'] = ftell($this->zip_fd);
|
3031 |
+
|
3032 |
+
// ----- Transform UNIX mtime to DOS format mdate/mtime
|
3033 |
+
$v_date = getdate($p_header['mtime']);
|
3034 |
+
$v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
|
3035 |
+
$v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
|
3036 |
+
|
3037 |
+
// ----- Packed data
|
3038 |
+
$v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
|
3039 |
+
$p_header['version_extracted'], $p_header['flag'],
|
3040 |
+
$p_header['compression'], $v_mtime, $v_mdate,
|
3041 |
+
$p_header['crc'], $p_header['compressed_size'],
|
3042 |
+
$p_header['size'],
|
3043 |
+
strlen($p_header['stored_filename']),
|
3044 |
+
$p_header['extra_len']);
|
3045 |
+
|
3046 |
+
// ----- Write the first 148 bytes of the header in the archive
|
3047 |
+
fputs($this->zip_fd, $v_binary_data, 30);
|
3048 |
+
|
3049 |
+
// ----- Write the variable fields
|
3050 |
+
if (strlen($p_header['stored_filename']) != 0)
|
3051 |
+
{
|
3052 |
+
fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
|
3053 |
+
}
|
3054 |
+
if ($p_header['extra_len'] != 0)
|
3055 |
+
{
|
3056 |
+
fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
|
3057 |
+
}
|
3058 |
+
|
3059 |
+
// ----- Return
|
3060 |
+
return $v_result;
|
3061 |
+
}
|
3062 |
+
// --------------------------------------------------------------------------------
|
3063 |
+
|
3064 |
+
// --------------------------------------------------------------------------------
|
3065 |
+
// Function : privWriteCentralFileHeader()
|
3066 |
+
// Description :
|
3067 |
+
// Parameters :
|
3068 |
+
// Return Values :
|
3069 |
+
// --------------------------------------------------------------------------------
|
3070 |
+
function privWriteCentralFileHeader(&$p_header)
|
3071 |
+
{
|
3072 |
+
$v_result=1;
|
3073 |
+
|
3074 |
+
// TBC
|
3075 |
+
//for(reset($p_header); $key = key($p_header); next($p_header)) {
|
3076 |
+
//}
|
3077 |
+
|
3078 |
+
// ----- Transform UNIX mtime to DOS format mdate/mtime
|
3079 |
+
$v_date = getdate($p_header['mtime']);
|
3080 |
+
$v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
|
3081 |
+
$v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
|
3082 |
+
|
3083 |
+
|
3084 |
+
// ----- Packed data
|
3085 |
+
$v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
|
3086 |
+
$p_header['version'], $p_header['version_extracted'],
|
3087 |
+
$p_header['flag'], $p_header['compression'],
|
3088 |
+
$v_mtime, $v_mdate, $p_header['crc'],
|
3089 |
+
$p_header['compressed_size'], $p_header['size'],
|
3090 |
+
strlen($p_header['stored_filename']),
|
3091 |
+
$p_header['extra_len'], $p_header['comment_len'],
|
3092 |
+
$p_header['disk'], $p_header['internal'],
|
3093 |
+
$p_header['external'], $p_header['offset']);
|
3094 |
+
|
3095 |
+
// ----- Write the 42 bytes of the header in the zip file
|
3096 |
+
fputs($this->zip_fd, $v_binary_data, 46);
|
3097 |
+
|
3098 |
+
// ----- Write the variable fields
|
3099 |
+
if (strlen($p_header['stored_filename']) != 0)
|
3100 |
+
{
|
3101 |
+
fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
|
3102 |
+
}
|
3103 |
+
if ($p_header['extra_len'] != 0)
|
3104 |
+
{
|
3105 |
+
fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
|
3106 |
+
}
|
3107 |
+
if ($p_header['comment_len'] != 0)
|
3108 |
+
{
|
3109 |
+
fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
|
3110 |
+
}
|
3111 |
+
|
3112 |
+
// ----- Return
|
3113 |
+
return $v_result;
|
3114 |
+
}
|
3115 |
+
// --------------------------------------------------------------------------------
|
3116 |
+
|
3117 |
+
// --------------------------------------------------------------------------------
|
3118 |
+
// Function : privWriteCentralHeader()
|
3119 |
+
// Description :
|
3120 |
+
// Parameters :
|
3121 |
+
// Return Values :
|
3122 |
+
// --------------------------------------------------------------------------------
|
3123 |
+
function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
|
3124 |
+
{
|
3125 |
+
$v_result=1;
|
3126 |
+
|
3127 |
+
// ----- Packed data
|
3128 |
+
$v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
|
3129 |
+
$p_nb_entries, $p_size,
|
3130 |
+
$p_offset, strlen($p_comment));
|
3131 |
+
|
3132 |
+
// ----- Write the 22 bytes of the header in the zip file
|
3133 |
+
fputs($this->zip_fd, $v_binary_data, 22);
|
3134 |
+
|
3135 |
+
// ----- Write the variable fields
|
3136 |
+
if (strlen($p_comment) != 0)
|
3137 |
+
{
|
3138 |
+
fputs($this->zip_fd, $p_comment, strlen($p_comment));
|
3139 |
+
}
|
3140 |
+
|
3141 |
+
// ----- Return
|
3142 |
+
return $v_result;
|
3143 |
+
}
|
3144 |
+
// --------------------------------------------------------------------------------
|
3145 |
+
|
3146 |
+
// --------------------------------------------------------------------------------
|
3147 |
+
// Function : privList()
|
3148 |
+
// Description :
|
3149 |
+
// Parameters :
|
3150 |
+
// Return Values :
|
3151 |
+
// --------------------------------------------------------------------------------
|
3152 |
+
function privList(&$p_list)
|
3153 |
+
{
|
3154 |
+
$v_result=1;
|
3155 |
+
|
3156 |
+
// ----- Magic quotes trick
|
3157 |
+
$this->privDisableMagicQuotes();
|
3158 |
+
|
3159 |
+
// ----- Open the zip file
|
3160 |
+
if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
|
3161 |
+
{
|
3162 |
+
// ----- Magic quotes trick
|
3163 |
+
$this->privSwapBackMagicQuotes();
|
3164 |
+
|
3165 |
+
// ----- Error log
|
3166 |
+
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
|
3167 |
+
|
3168 |
+
// ----- Return
|
3169 |
+
return PclZip::errorCode();
|
3170 |
+
}
|
3171 |
+
|
3172 |
+
// ----- Read the central directory informations
|
3173 |
+
$v_central_dir = array();
|
3174 |
+
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
|
3175 |
+
{
|
3176 |
+
$this->privSwapBackMagicQuotes();
|
3177 |
+
return $v_result;
|
3178 |
+
}
|
3179 |
+
|
3180 |
+
// ----- Go to beginning of Central Dir
|
3181 |
+
@rewind($this->zip_fd);
|
3182 |
+
if (@fseek($this->zip_fd, $v_central_dir['offset']))
|
3183 |
+
{
|
3184 |
+
$this->privSwapBackMagicQuotes();
|
3185 |
+
|
3186 |
+
// ----- Error log
|
3187 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
|
3188 |
+
|
3189 |
+
// ----- Return
|
3190 |
+
return PclZip::errorCode();
|
3191 |
+
}
|
3192 |
+
|
3193 |
+
// ----- Read each entry
|
3194 |
+
for ($i=0; $i<$v_central_dir['entries']; $i++)
|
3195 |
+
{
|
3196 |
+
// ----- Read the file header
|
3197 |
+
if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
|
3198 |
+
{
|
3199 |
+
$this->privSwapBackMagicQuotes();
|
3200 |
+
return $v_result;
|
3201 |
+
}
|
3202 |
+
$v_header['index'] = $i;
|
3203 |
+
|
3204 |
+
// ----- Get the only interesting attributes
|
3205 |
+
$this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
|
3206 |
+
unset($v_header);
|
3207 |
+
}
|
3208 |
+
|
3209 |
+
// ----- Close the zip file
|
3210 |
+
$this->privCloseFd();
|
3211 |
+
|
3212 |
+
// ----- Magic quotes trick
|
3213 |
+
$this->privSwapBackMagicQuotes();
|
3214 |
+
|
3215 |
+
// ----- Return
|
3216 |
+
return $v_result;
|
3217 |
+
}
|
3218 |
+
// --------------------------------------------------------------------------------
|
3219 |
+
|
3220 |
+
// --------------------------------------------------------------------------------
|
3221 |
+
// Function : privConvertHeader2FileInfo()
|
3222 |
+
// Description :
|
3223 |
+
// This function takes the file informations from the central directory
|
3224 |
+
// entries and extract the interesting parameters that will be given back.
|
3225 |
+
// The resulting file infos are set in the array $p_info
|
3226 |
+
// $p_info['filename'] : Filename with full path. Given by user (add),
|
3227 |
+
// extracted in the filesystem (extract).
|
3228 |
+
// $p_info['stored_filename'] : Stored filename in the archive.
|
3229 |
+
// $p_info['size'] = Size of the file.
|
3230 |
+
// $p_info['compressed_size'] = Compressed size of the file.
|
3231 |
+
// $p_info['mtime'] = Last modification date of the file.
|
3232 |
+
// $p_info['comment'] = Comment associated with the file.
|
3233 |
+
// $p_info['folder'] = true/false : indicates if the entry is a folder or not.
|
3234 |
+
// $p_info['status'] = status of the action on the file.
|
3235 |
+
// $p_info['crc'] = CRC of the file content.
|
3236 |
+
// Parameters :
|
3237 |
+
// Return Values :
|
3238 |
+
// --------------------------------------------------------------------------------
|
3239 |
+
function privConvertHeader2FileInfo($p_header, &$p_info)
|
3240 |
+
{
|
3241 |
+
$v_result=1;
|
3242 |
+
|
3243 |
+
// ----- Get the interesting attributes
|
3244 |
+
$v_temp_path = PclZipUtilPathReduction($p_header['filename']);
|
3245 |
+
$p_info['filename'] = $v_temp_path;
|
3246 |
+
$v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
|
3247 |
+
$p_info['stored_filename'] = $v_temp_path;
|
3248 |
+
$p_info['size'] = $p_header['size'];
|
3249 |
+
$p_info['compressed_size'] = $p_header['compressed_size'];
|
3250 |
+
$p_info['mtime'] = $p_header['mtime'];
|
3251 |
+
$p_info['comment'] = $p_header['comment'];
|
3252 |
+
$p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
|
3253 |
+
$p_info['index'] = $p_header['index'];
|
3254 |
+
$p_info['status'] = $p_header['status'];
|
3255 |
+
$p_info['crc'] = $p_header['crc'];
|
3256 |
+
|
3257 |
+
// ----- Return
|
3258 |
+
return $v_result;
|
3259 |
+
}
|
3260 |
+
// --------------------------------------------------------------------------------
|
3261 |
+
|
3262 |
+
// --------------------------------------------------------------------------------
|
3263 |
+
// Function : privExtractByRule()
|
3264 |
+
// Description :
|
3265 |
+
// Extract a file or directory depending of rules (by index, by name, ...)
|
3266 |
+
// Parameters :
|
3267 |
+
// $p_file_list : An array where will be placed the properties of each
|
3268 |
+
// extracted file
|
3269 |
+
// $p_path : Path to add while writing the extracted files
|
3270 |
+
// $p_remove_path : Path to remove (from the file memorized path) while writing the
|
3271 |
+
// extracted files. If the path does not match the file path,
|
3272 |
+
// the file is extracted with its memorized path.
|
3273 |
+
// $p_remove_path does not apply to 'list' mode.
|
3274 |
+
// $p_path and $p_remove_path are commulative.
|
3275 |
+
// Return Values :
|
3276 |
+
// 1 on success,0 or less on error (see error code list)
|
3277 |
+
// --------------------------------------------------------------------------------
|
3278 |
+
function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
|
3279 |
+
{
|
3280 |
+
$v_result=1;
|
3281 |
+
|
3282 |
+
// ----- Magic quotes trick
|
3283 |
+
$this->privDisableMagicQuotes();
|
3284 |
+
|
3285 |
+
// ----- Check the path
|
3286 |
+
if ( ($p_path == "")
|
3287 |
+
|| ( (substr($p_path, 0, 1) != "/")
|
3288 |
+
&& (substr($p_path, 0, 3) != "../")
|
3289 |
+
&& (substr($p_path,1,2)!=":/")))
|
3290 |
+
$p_path = "./".$p_path;
|
3291 |
+
|
3292 |
+
// ----- Reduce the path last (and duplicated) '/'
|
3293 |
+
if (($p_path != "./") && ($p_path != "/"))
|
3294 |
+
{
|
3295 |
+
// ----- Look for the path end '/'
|
3296 |
+
while (substr($p_path, -1) == "/")
|
3297 |
+
{
|
3298 |
+
$p_path = substr($p_path, 0, strlen($p_path)-1);
|
3299 |
+
}
|
3300 |
+
}
|
3301 |
+
|
3302 |
+
// ----- Look for path to remove format (should end by /)
|
3303 |
+
if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
|
3304 |
+
{
|
3305 |
+
$p_remove_path .= '/';
|
3306 |
+
}
|
3307 |
+
$p_remove_path_size = strlen($p_remove_path);
|
3308 |
+
|
3309 |
+
// ----- Open the zip file
|
3310 |
+
if (($v_result = $this->privOpenFd('rb')) != 1)
|
3311 |
+
{
|
3312 |
+
$this->privSwapBackMagicQuotes();
|
3313 |
+
return $v_result;
|
3314 |
+
}
|
3315 |
+
|
3316 |
+
// ----- Read the central directory informations
|
3317 |
+
$v_central_dir = array();
|
3318 |
+
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
|
3319 |
+
{
|
3320 |
+
// ----- Close the zip file
|
3321 |
+
$this->privCloseFd();
|
3322 |
+
$this->privSwapBackMagicQuotes();
|
3323 |
+
|
3324 |
+
return $v_result;
|
3325 |
+
}
|
3326 |
+
|
3327 |
+
// ----- Start at beginning of Central Dir
|
3328 |
+
$v_pos_entry = $v_central_dir['offset'];
|
3329 |
+
|
3330 |
+
// ----- Read each entry
|
3331 |
+
$j_start = 0;
|
3332 |
+
for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
|
3333 |
+
{
|
3334 |
+
|
3335 |
+
// ----- Read next Central dir entry
|
3336 |
+
@rewind($this->zip_fd);
|
3337 |
+
if (@fseek($this->zip_fd, $v_pos_entry))
|
3338 |
+
{
|
3339 |
+
// ----- Close the zip file
|
3340 |
+
$this->privCloseFd();
|
3341 |
+
$this->privSwapBackMagicQuotes();
|
3342 |
+
|
3343 |
+
// ----- Error log
|
3344 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
|
3345 |
+
|
3346 |
+
// ----- Return
|
3347 |
+
return PclZip::errorCode();
|
3348 |
+
}
|
3349 |
+
|
3350 |
+
// ----- Read the file header
|
3351 |
+
$v_header = array();
|
3352 |
+
if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
|
3353 |
+
{
|
3354 |
+
// ----- Close the zip file
|
3355 |
+
$this->privCloseFd();
|
3356 |
+
$this->privSwapBackMagicQuotes();
|
3357 |
+
|
3358 |
+
return $v_result;
|
3359 |
+
}
|
3360 |
+
|
3361 |
+
// ----- Store the index
|
3362 |
+
$v_header['index'] = $i;
|
3363 |
+
|
3364 |
+
// ----- Store the file position
|
3365 |
+
$v_pos_entry = ftell($this->zip_fd);
|
3366 |
+
|
3367 |
+
// ----- Look for the specific extract rules
|
3368 |
+
$v_extract = false;
|
3369 |
+
|
3370 |
+
// ----- Look for extract by name rule
|
3371 |
+
if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
|
3372 |
+
&& ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
|
3373 |
+
|
3374 |
+
// ----- Look if the filename is in the list
|
3375 |
+
for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
|
3376 |
+
|
3377 |
+
// ----- Look for a directory
|
3378 |
+
if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
|
3379 |
+
|
3380 |
+
// ----- Look if the directory is in the filename path
|
3381 |
+
if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
|
3382 |
+
&& (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
|
3383 |
+
$v_extract = true;
|
3384 |
+
}
|
3385 |
+
}
|
3386 |
+
// ----- Look for a filename
|
3387 |
+
elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
|
3388 |
+
$v_extract = true;
|
3389 |
+
}
|
3390 |
+
}
|
3391 |
+
}
|
3392 |
+
|
3393 |
+
// ----- Look for extract by ereg rule
|
3394 |
+
// ereg() is deprecated with PHP 5.3
|
3395 |
+
/*
|
3396 |
+
else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
|
3397 |
+
&& ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
|
3398 |
+
|
3399 |
+
if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
|
3400 |
+
$v_extract = true;
|
3401 |
+
}
|
3402 |
+
}
|
3403 |
+
*/
|
3404 |
+
|
3405 |
+
// ----- Look for extract by preg rule
|
3406 |
+
else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
|
3407 |
+
&& ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
|
3408 |
+
|
3409 |
+
if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
|
3410 |
+
$v_extract = true;
|
3411 |
+
}
|
3412 |
+
}
|
3413 |
+
|
3414 |
+
// ----- Look for extract by index rule
|
3415 |
+
else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
|
3416 |
+
&& ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
|
3417 |
+
|
3418 |
+
// ----- Look if the index is in the list
|
3419 |
+
for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
|
3420 |
+
|
3421 |
+
if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
|
3422 |
+
$v_extract = true;
|
3423 |
+
}
|
3424 |
+
if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
|
3425 |
+
$j_start = $j+1;
|
3426 |
+
}
|
3427 |
+
|
3428 |
+
if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
|
3429 |
+
break;
|
3430 |
+
}
|
3431 |
+
}
|
3432 |
+
}
|
3433 |
+
|
3434 |
+
// ----- Look for no rule, which means extract all the archive
|
3435 |
+
else {
|
3436 |
+
$v_extract = true;
|
3437 |
+
}
|
3438 |
+
|
3439 |
+
// ----- Check compression method
|
3440 |
+
if ( ($v_extract)
|
3441 |
+
&& ( ($v_header['compression'] != 8)
|
3442 |
+
&& ($v_header['compression'] != 0))) {
|
3443 |
+
$v_header['status'] = 'unsupported_compression';
|
3444 |
+
|
3445 |
+
// ----- Look for PCLZIP_OPT_STOP_ON_ERROR
|
3446 |
+
if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
|
3447 |
+
&& ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
|
3448 |
+
|
3449 |
+
$this->privSwapBackMagicQuotes();
|
3450 |
+
|
3451 |
+
PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
|
3452 |
+
"Filename '".$v_header['stored_filename']."' is "
|
3453 |
+
."compressed by an unsupported compression "
|
3454 |
+
."method (".$v_header['compression'].") ");
|
3455 |
+
|
3456 |
+
return PclZip::errorCode();
|
3457 |
+
}
|
3458 |
+
}
|
3459 |
+
|
3460 |
+
// ----- Check encrypted files
|
3461 |
+
if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
|
3462 |
+
$v_header['status'] = 'unsupported_encryption';
|
3463 |
+
|
3464 |
+
// ----- Look for PCLZIP_OPT_STOP_ON_ERROR
|
3465 |
+
if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
|
3466 |
+
&& ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
|
3467 |
+
|
3468 |
+
$this->privSwapBackMagicQuotes();
|
3469 |
+
|
3470 |
+
PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
|
3471 |
+
"Unsupported encryption for "
|
3472 |
+
." filename '".$v_header['stored_filename']
|
3473 |
+
."'");
|
3474 |
+
|
3475 |
+
return PclZip::errorCode();
|
3476 |
+
}
|
3477 |
+
}
|
3478 |
+
|
3479 |
+
// ----- Look for real extraction
|
3480 |
+
if (($v_extract) && ($v_header['status'] != 'ok')) {
|
3481 |
+
$v_result = $this->privConvertHeader2FileInfo($v_header,
|
3482 |
+
$p_file_list[$v_nb_extracted++]);
|
3483 |
+
if ($v_result != 1) {
|
3484 |
+
$this->privCloseFd();
|
3485 |
+
$this->privSwapBackMagicQuotes();
|
3486 |
+
return $v_result;
|
3487 |
+
}
|
3488 |
+
|
3489 |
+
$v_extract = false;
|
3490 |
+
}
|
3491 |
+
|
3492 |
+
// ----- Look for real extraction
|
3493 |
+
if ($v_extract)
|
3494 |
+
{
|
3495 |
+
|
3496 |
+
// ----- Go to the file position
|
3497 |
+
@rewind($this->zip_fd);
|
3498 |
+
if (@fseek($this->zip_fd, $v_header['offset']))
|
3499 |
+
{
|
3500 |
+
// ----- Close the zip file
|
3501 |
+
$this->privCloseFd();
|
3502 |
+
|
3503 |
+
$this->privSwapBackMagicQuotes();
|
3504 |
+
|
3505 |
+
// ----- Error log
|
3506 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
|
3507 |
+
|
3508 |
+
// ----- Return
|
3509 |
+
return PclZip::errorCode();
|
3510 |
+
}
|
3511 |
+
|
3512 |
+
// ----- Look for extraction as string
|
3513 |
+
if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
|
3514 |
+
|
3515 |
+
$v_string = '';
|
3516 |
+
|
3517 |
+
// ----- Extracting the file
|
3518 |
+
$v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
|
3519 |
+
if ($v_result1 < 1) {
|
3520 |
+
$this->privCloseFd();
|
3521 |
+
$this->privSwapBackMagicQuotes();
|
3522 |
+
return $v_result1;
|
3523 |
+
}
|
3524 |
+
|
3525 |
+
// ----- Get the only interesting attributes
|
3526 |
+
if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
|
3527 |
+
{
|
3528 |
+
// ----- Close the zip file
|
3529 |
+
$this->privCloseFd();
|
3530 |
+
$this->privSwapBackMagicQuotes();
|
3531 |
+
|
3532 |
+
return $v_result;
|
3533 |
+
}
|
3534 |
+
|
3535 |
+
// ----- Set the file content
|
3536 |
+
$p_file_list[$v_nb_extracted]['content'] = $v_string;
|
3537 |
+
|
3538 |
+
// ----- Next extracted file
|
3539 |
+
$v_nb_extracted++;
|
3540 |
+
|
3541 |
+
// ----- Look for user callback abort
|
3542 |
+
if ($v_result1 == 2) {
|
3543 |
+
break;
|
3544 |
+
}
|
3545 |
+
}
|
3546 |
+
// ----- Look for extraction in standard output
|
3547 |
+
elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
|
3548 |
+
&& ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
|
3549 |
+
// ----- Extracting the file in standard output
|
3550 |
+
$v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
|
3551 |
+
if ($v_result1 < 1) {
|
3552 |
+
$this->privCloseFd();
|
3553 |
+
$this->privSwapBackMagicQuotes();
|
3554 |
+
return $v_result1;
|
3555 |
+
}
|
3556 |
+
|
3557 |
+
// ----- Get the only interesting attributes
|
3558 |
+
if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
|
3559 |
+
$this->privCloseFd();
|
3560 |
+
$this->privSwapBackMagicQuotes();
|
3561 |
+
return $v_result;
|
3562 |
+
}
|
3563 |
+
|
3564 |
+
// ----- Look for user callback abort
|
3565 |
+
if ($v_result1 == 2) {
|
3566 |
+
break;
|
3567 |
+
}
|
3568 |
+
}
|
3569 |
+
// ----- Look for normal extraction
|
3570 |
+
else {
|
3571 |
+
// ----- Extracting the file
|
3572 |
+
$v_result1 = $this->privExtractFile($v_header,
|
3573 |
+
$p_path, $p_remove_path,
|
3574 |
+
$p_remove_all_path,
|
3575 |
+
$p_options);
|
3576 |
+
if ($v_result1 < 1) {
|
3577 |
+
$this->privCloseFd();
|
3578 |
+
$this->privSwapBackMagicQuotes();
|
3579 |
+
return $v_result1;
|
3580 |
+
}
|
3581 |
+
|
3582 |
+
// ----- Get the only interesting attributes
|
3583 |
+
if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
|
3584 |
+
{
|
3585 |
+
// ----- Close the zip file
|
3586 |
+
$this->privCloseFd();
|
3587 |
+
$this->privSwapBackMagicQuotes();
|
3588 |
+
|
3589 |
+
return $v_result;
|
3590 |
+
}
|
3591 |
+
|
3592 |
+
// ----- Look for user callback abort
|
3593 |
+
if ($v_result1 == 2) {
|
3594 |
+
break;
|
3595 |
+
}
|
3596 |
+
}
|
3597 |
+
}
|
3598 |
+
}
|
3599 |
+
|
3600 |
+
// ----- Close the zip file
|
3601 |
+
$this->privCloseFd();
|
3602 |
+
$this->privSwapBackMagicQuotes();
|
3603 |
+
|
3604 |
+
// ----- Return
|
3605 |
+
return $v_result;
|
3606 |
+
}
|
3607 |
+
// --------------------------------------------------------------------------------
|
3608 |
+
|
3609 |
+
// --------------------------------------------------------------------------------
|
3610 |
+
// Function : privExtractFile()
|
3611 |
+
// Description :
|
3612 |
+
// Parameters :
|
3613 |
+
// Return Values :
|
3614 |
+
//
|
3615 |
+
// 1 : ... ?
|
3616 |
+
// PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
|
3617 |
+
// --------------------------------------------------------------------------------
|
3618 |
+
function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
|
3619 |
+
{
|
3620 |
+
$v_result=1;
|
3621 |
+
|
3622 |
+
// ----- Read the file header
|
3623 |
+
if (($v_result = $this->privReadFileHeader($v_header)) != 1)
|
3624 |
+
{
|
3625 |
+
// ----- Return
|
3626 |
+
return $v_result;
|
3627 |
+
}
|
3628 |
+
|
3629 |
+
|
3630 |
+
// ----- Check that the file header is coherent with $p_entry info
|
3631 |
+
if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
|
3632 |
+
// TBC
|
3633 |
+
}
|
3634 |
+
|
3635 |
+
// ----- Look for all path to remove
|
3636 |
+
if ($p_remove_all_path == true) {
|
3637 |
+
// ----- Look for folder entry that not need to be extracted
|
3638 |
+
if (($p_entry['external']&0x00000010)==0x00000010) {
|
3639 |
+
|
3640 |
+
$p_entry['status'] = "filtered";
|
3641 |
+
|
3642 |
+
return $v_result;
|
3643 |
+
}
|
3644 |
+
|
3645 |
+
// ----- Get the basename of the path
|
3646 |
+
$p_entry['filename'] = basename($p_entry['filename']);
|
3647 |
+
}
|
3648 |
+
|
3649 |
+
// ----- Look for path to remove
|
3650 |
+
else if ($p_remove_path != "")
|
3651 |
+
{
|
3652 |
+
if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
|
3653 |
+
{
|
3654 |
+
|
3655 |
+
// ----- Change the file status
|
3656 |
+
$p_entry['status'] = "filtered";
|
3657 |
+
|
3658 |
+
// ----- Return
|
3659 |
+
return $v_result;
|
3660 |
+
}
|
3661 |
+
|
3662 |
+
$p_remove_path_size = strlen($p_remove_path);
|
3663 |
+
if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
|
3664 |
+
{
|
3665 |
+
|
3666 |
+
// ----- Remove the path
|
3667 |
+
$p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
|
3668 |
+
|
3669 |
+
}
|
3670 |
+
}
|
3671 |
+
|
3672 |
+
// ----- Add the path
|
3673 |
+
if ($p_path != '') {
|
3674 |
+
$p_entry['filename'] = $p_path."/".$p_entry['filename'];
|
3675 |
+
}
|
3676 |
+
|
3677 |
+
// ----- Check a base_dir_restriction
|
3678 |
+
if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
|
3679 |
+
$v_inclusion
|
3680 |
+
= PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
|
3681 |
+
$p_entry['filename']);
|
3682 |
+
if ($v_inclusion == 0) {
|
3683 |
+
|
3684 |
+
PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
|
3685 |
+
"Filename '".$p_entry['filename']."' is "
|
3686 |
+
."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
|
3687 |
+
|
3688 |
+
return PclZip::errorCode();
|
3689 |
+
}
|
3690 |
+
}
|
3691 |
+
|
3692 |
+
// ----- Look for pre-extract callback
|
3693 |
+
if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
|
3694 |
+
|
3695 |
+
// ----- Generate a local information
|
3696 |
+
$v_local_header = array();
|
3697 |
+
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
|
3698 |
+
|
3699 |
+
// ----- Call the callback
|
3700 |
+
// Here I do not use call_user_func() because I need to send a reference to the
|
3701 |
+
// header.
|
3702 |
+
// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
|
3703 |
+
$v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
|
3704 |
+
if ($v_result == 0) {
|
3705 |
+
// ----- Change the file status
|
3706 |
+
$p_entry['status'] = "skipped";
|
3707 |
+
$v_result = 1;
|
3708 |
+
}
|
3709 |
+
|
3710 |
+
// ----- Look for abort result
|
3711 |
+
if ($v_result == 2) {
|
3712 |
+
// ----- This status is internal and will be changed in 'skipped'
|
3713 |
+
$p_entry['status'] = "aborted";
|
3714 |
+
$v_result = PCLZIP_ERR_USER_ABORTED;
|
3715 |
+
}
|
3716 |
+
|
3717 |
+
// ----- Update the informations
|
3718 |
+
// Only some fields can be modified
|
3719 |
+
$p_entry['filename'] = $v_local_header['filename'];
|
3720 |
+
}
|
3721 |
+
|
3722 |
+
|
3723 |
+
// ----- Look if extraction should be done
|
3724 |
+
if ($p_entry['status'] == 'ok') {
|
3725 |
+
|
3726 |
+
// ----- Look for specific actions while the file exist
|
3727 |
+
if (file_exists($p_entry['filename']))
|
3728 |
+
{
|
3729 |
+
|
3730 |
+
// ----- Look if file is a directory
|
3731 |
+
if (is_dir($p_entry['filename']))
|
3732 |
+
{
|
3733 |
+
|
3734 |
+
// ----- Change the file status
|
3735 |
+
$p_entry['status'] = "already_a_directory";
|
3736 |
+
|
3737 |
+
// ----- Look for PCLZIP_OPT_STOP_ON_ERROR
|
3738 |
+
// For historical reason first PclZip implementation does not stop
|
3739 |
+
// when this kind of error occurs.
|
3740 |
+
if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
|
3741 |
+
&& ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
|
3742 |
+
|
3743 |
+
PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
|
3744 |
+
"Filename '".$p_entry['filename']."' is "
|
3745 |
+
."already used by an existing directory");
|
3746 |
+
|
3747 |
+
return PclZip::errorCode();
|
3748 |
+
}
|
3749 |
+
}
|
3750 |
+
// ----- Look if file is write protected
|
3751 |
+
else if (!is_writeable($p_entry['filename']))
|
3752 |
+
{
|
3753 |
+
|
3754 |
+
// ----- Change the file status
|
3755 |
+
$p_entry['status'] = "write_protected";
|
3756 |
+
|
3757 |
+
// ----- Look for PCLZIP_OPT_STOP_ON_ERROR
|
3758 |
+
// For historical reason first PclZip implementation does not stop
|
3759 |
+
// when this kind of error occurs.
|
3760 |
+
if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
|
3761 |
+
&& ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
|
3762 |
+
|
3763 |
+
PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
|
3764 |
+
"Filename '".$p_entry['filename']."' exists "
|
3765 |
+
."and is write protected");
|
3766 |
+
|
3767 |
+
return PclZip::errorCode();
|
3768 |
+
}
|
3769 |
+
}
|
3770 |
+
|
3771 |
+
// ----- Look if the extracted file is older
|
3772 |
+
else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
|
3773 |
+
{
|
3774 |
+
// ----- Change the file status
|
3775 |
+
if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
|
3776 |
+
&& ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
|
3777 |
+
}
|
3778 |
+
else {
|
3779 |
+
$p_entry['status'] = "newer_exist";
|
3780 |
+
|
3781 |
+
// ----- Look for PCLZIP_OPT_STOP_ON_ERROR
|
3782 |
+
// For historical reason first PclZip implementation does not stop
|
3783 |
+
// when this kind of error occurs.
|
3784 |
+
if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
|
3785 |
+
&& ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
|
3786 |
+
|
3787 |
+
PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
|
3788 |
+
"Newer version of '".$p_entry['filename']."' exists "
|
3789 |
+
."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
|
3790 |
+
|
3791 |
+
return PclZip::errorCode();
|
3792 |
+
}
|
3793 |
+
}
|
3794 |
+
}
|
3795 |
+
else {
|
3796 |
+
}
|
3797 |
+
}
|
3798 |
+
|
3799 |
+
// ----- Check the directory availability and create it if necessary
|
3800 |
+
else {
|
3801 |
+
if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
|
3802 |
+
$v_dir_to_check = $p_entry['filename'];
|
3803 |
+
else if (!strstr($p_entry['filename'], "/"))
|
3804 |
+
$v_dir_to_check = "";
|
3805 |
+
else
|
3806 |
+
$v_dir_to_check = dirname($p_entry['filename']);
|
3807 |
+
|
3808 |
+
if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
|
3809 |
+
|
3810 |
+
// ----- Change the file status
|
3811 |
+
$p_entry['status'] = "path_creation_fail";
|
3812 |
+
|
3813 |
+
// ----- Return
|
3814 |
+
//return $v_result;
|
3815 |
+
$v_result = 1;
|
3816 |
+
}
|
3817 |
+
}
|
3818 |
+
}
|
3819 |
+
|
3820 |
+
// ----- Look if extraction should be done
|
3821 |
+
if ($p_entry['status'] == 'ok') {
|
3822 |
+
|
3823 |
+
// ----- Do the extraction (if not a folder)
|
3824 |
+
if (!(($p_entry['external']&0x00000010)==0x00000010))
|
3825 |
+
{
|
3826 |
+
// ----- Look for not compressed file
|
3827 |
+
if ($p_entry['compression'] == 0) {
|
3828 |
+
|
3829 |
+
// ----- Opening destination file
|
3830 |
+
if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
|
3831 |
+
{
|
3832 |
+
|
3833 |
+
// ----- Change the file status
|
3834 |
+
$p_entry['status'] = "write_error";
|
3835 |
+
|
3836 |
+
// ----- Return
|
3837 |
+
return $v_result;
|
3838 |
+
}
|
3839 |
+
|
3840 |
+
|
3841 |
+
// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
|
3842 |
+
$v_size = $p_entry['compressed_size'];
|
3843 |
+
while ($v_size != 0)
|
3844 |
+
{
|
3845 |
+
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
|
3846 |
+
$v_buffer = @fread($this->zip_fd, $v_read_size);
|
3847 |
+
/* Try to speed up the code
|
3848 |
+
$v_binary_data = pack('a'.$v_read_size, $v_buffer);
|
3849 |
+
@fwrite($v_dest_file, $v_binary_data, $v_read_size);
|
3850 |
+
*/
|
3851 |
+
@fwrite($v_dest_file, $v_buffer, $v_read_size);
|
3852 |
+
$v_size -= $v_read_size;
|
3853 |
+
}
|
3854 |
+
|
3855 |
+
// ----- Closing the destination file
|
3856 |
+
fclose($v_dest_file);
|
3857 |
+
|
3858 |
+
// ----- Change the file mtime
|
3859 |
+
touch($p_entry['filename'], $p_entry['mtime']);
|
3860 |
+
|
3861 |
+
|
3862 |
+
}
|
3863 |
+
else {
|
3864 |
+
// ----- TBC
|
3865 |
+
// Need to be finished
|
3866 |
+
if (($p_entry['flag'] & 1) == 1) {
|
3867 |
+
PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.');
|
3868 |
+
return PclZip::errorCode();
|
3869 |
+
}
|
3870 |
+
|
3871 |
+
|
3872 |
+
// ----- Look for using temporary file to unzip
|
3873 |
+
if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
|
3874 |
+
&& (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
|
3875 |
+
|| (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
|
3876 |
+
&& ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {
|
3877 |
+
$v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
|
3878 |
+
if ($v_result < PCLZIP_ERR_NO_ERROR) {
|
3879 |
+
return $v_result;
|
3880 |
+
}
|
3881 |
+
}
|
3882 |
+
|
3883 |
+
// ----- Look for extract in memory
|
3884 |
+
else {
|
3885 |
+
|
3886 |
+
|
3887 |
+
// ----- Read the compressed file in a buffer (one shot)
|
3888 |
+
$v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
|
3889 |
+
|
3890 |
+
// ----- Decompress the file
|
3891 |
+
$v_file_content = @gzinflate($v_buffer);
|
3892 |
+
unset($v_buffer);
|
3893 |
+
if ($v_file_content === FALSE) {
|
3894 |
+
|
3895 |
+
// ----- Change the file status
|
3896 |
+
// TBC
|
3897 |
+
$p_entry['status'] = "error";
|
3898 |
+
|
3899 |
+
return $v_result;
|
3900 |
+
}
|
3901 |
+
|
3902 |
+
// ----- Opening destination file
|
3903 |
+
if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
|
3904 |
+
|
3905 |
+
// ----- Change the file status
|
3906 |
+
$p_entry['status'] = "write_error";
|
3907 |
+
|
3908 |
+
return $v_result;
|
3909 |
+
}
|
3910 |
+
|
3911 |
+
// ----- Write the uncompressed data
|
3912 |
+
@fwrite($v_dest_file, $v_file_content, $p_entry['size']);
|
3913 |
+
unset($v_file_content);
|
3914 |
+
|
3915 |
+
// ----- Closing the destination file
|
3916 |
+
@fclose($v_dest_file);
|
3917 |
+
|
3918 |
+
}
|
3919 |
+
|
3920 |
+
// ----- Change the file mtime
|
3921 |
+
@touch($p_entry['filename'], $p_entry['mtime']);
|
3922 |
+
}
|
3923 |
+
|
3924 |
+
// ----- Look for chmod option
|
3925 |
+
if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
|
3926 |
+
|
3927 |
+
// ----- Change the mode of the file
|
3928 |
+
@chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
|
3929 |
+
}
|
3930 |
+
|
3931 |
+
}
|
3932 |
+
}
|
3933 |
+
|
3934 |
+
// ----- Change abort status
|
3935 |
+
if ($p_entry['status'] == "aborted") {
|
3936 |
+
$p_entry['status'] = "skipped";
|
3937 |
+
}
|
3938 |
+
|
3939 |
+
// ----- Look for post-extract callback
|
3940 |
+
elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
|
3941 |
+
|
3942 |
+
// ----- Generate a local information
|
3943 |
+
$v_local_header = array();
|
3944 |
+
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
|
3945 |
+
|
3946 |
+
// ----- Call the callback
|
3947 |
+
// Here I do not use call_user_func() because I need to send a reference to the
|
3948 |
+
// header.
|
3949 |
+
// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
|
3950 |
+
$v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
|
3951 |
+
|
3952 |
+
// ----- Look for abort result
|
3953 |
+
if ($v_result == 2) {
|
3954 |
+
$v_result = PCLZIP_ERR_USER_ABORTED;
|
3955 |
+
}
|
3956 |
+
}
|
3957 |
+
|
3958 |
+
// ----- Return
|
3959 |
+
return $v_result;
|
3960 |
+
}
|
3961 |
+
// --------------------------------------------------------------------------------
|
3962 |
+
|
3963 |
+
// --------------------------------------------------------------------------------
|
3964 |
+
// Function : privExtractFileUsingTempFile()
|
3965 |
+
// Description :
|
3966 |
+
// Parameters :
|
3967 |
+
// Return Values :
|
3968 |
+
// --------------------------------------------------------------------------------
|
3969 |
+
function privExtractFileUsingTempFile(&$p_entry, &$p_options)
|
3970 |
+
{
|
3971 |
+
$v_result=1;
|
3972 |
+
|
3973 |
+
// ----- Creates a temporary file
|
3974 |
+
$v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
|
3975 |
+
if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
|
3976 |
+
fclose($v_file);
|
3977 |
+
PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
|
3978 |
+
return PclZip::errorCode();
|
3979 |
+
}
|
3980 |
+
|
3981 |
+
|
3982 |
+
// ----- Write gz file format header
|
3983 |
+
$v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
|
3984 |
+
@fwrite($v_dest_file, $v_binary_data, 10);
|
3985 |
+
|
3986 |
+
// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
|
3987 |
+
$v_size = $p_entry['compressed_size'];
|
3988 |
+
while ($v_size != 0)
|
3989 |
+
{
|
3990 |
+
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
|
3991 |
+
$v_buffer = @fread($this->zip_fd, $v_read_size);
|
3992 |
+
//$v_binary_data = pack('a'.$v_read_size, $v_buffer);
|
3993 |
+
@fwrite($v_dest_file, $v_buffer, $v_read_size);
|
3994 |
+
$v_size -= $v_read_size;
|
3995 |
+
}
|
3996 |
+
|
3997 |
+
// ----- Write gz file format footer
|
3998 |
+
$v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
|
3999 |
+
@fwrite($v_dest_file, $v_binary_data, 8);
|
4000 |
+
|
4001 |
+
// ----- Close the temporary file
|
4002 |
+
@fclose($v_dest_file);
|
4003 |
+
|
4004 |
+
// ----- Opening destination file
|
4005 |
+
if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
|
4006 |
+
$p_entry['status'] = "write_error";
|
4007 |
+
return $v_result;
|
4008 |
+
}
|
4009 |
+
|
4010 |
+
// ----- Open the temporary gz file
|
4011 |
+
if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
|
4012 |
+
@fclose($v_dest_file);
|
4013 |
+
$p_entry['status'] = "read_error";
|
4014 |
+
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
|
4015 |
+
return PclZip::errorCode();
|
4016 |
+
}
|
4017 |
+
|
4018 |
+
|
4019 |
+
// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
|
4020 |
+
$v_size = $p_entry['size'];
|
4021 |
+
while ($v_size != 0) {
|
4022 |
+
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
|
4023 |
+
$v_buffer = @gzread($v_src_file, $v_read_size);
|
4024 |
+
//$v_binary_data = pack('a'.$v_read_size, $v_buffer);
|
4025 |
+
@fwrite($v_dest_file, $v_buffer, $v_read_size);
|
4026 |
+
$v_size -= $v_read_size;
|
4027 |
+
}
|
4028 |
+
@fclose($v_dest_file);
|
4029 |
+
@gzclose($v_src_file);
|
4030 |
+
|
4031 |
+
// ----- Delete the temporary file
|
4032 |
+
@unlink($v_gzip_temp_name);
|
4033 |
+
|
4034 |
+
// ----- Return
|
4035 |
+
return $v_result;
|
4036 |
+
}
|
4037 |
+
// --------------------------------------------------------------------------------
|
4038 |
+
|
4039 |
+
// --------------------------------------------------------------------------------
|
4040 |
+
// Function : privExtractFileInOutput()
|
4041 |
+
// Description :
|
4042 |
+
// Parameters :
|
4043 |
+
// Return Values :
|
4044 |
+
// --------------------------------------------------------------------------------
|
4045 |
+
function privExtractFileInOutput(&$p_entry, &$p_options)
|
4046 |
+
{
|
4047 |
+
$v_result=1;
|
4048 |
+
|
4049 |
+
// ----- Read the file header
|
4050 |
+
if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
|
4051 |
+
return $v_result;
|
4052 |
+
}
|
4053 |
+
|
4054 |
+
|
4055 |
+
// ----- Check that the file header is coherent with $p_entry info
|
4056 |
+
if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
|
4057 |
+
// TBC
|
4058 |
+
}
|
4059 |
+
|
4060 |
+
// ----- Look for pre-extract callback
|
4061 |
+
if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
|
4062 |
+
|
4063 |
+
// ----- Generate a local information
|
4064 |
+
$v_local_header = array();
|
4065 |
+
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
|
4066 |
+
|
4067 |
+
// ----- Call the callback
|
4068 |
+
// Here I do not use call_user_func() because I need to send a reference to the
|
4069 |
+
// header.
|
4070 |
+
// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
|
4071 |
+
$v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
|
4072 |
+
if ($v_result == 0) {
|
4073 |
+
// ----- Change the file status
|
4074 |
+
$p_entry['status'] = "skipped";
|
4075 |
+
$v_result = 1;
|
4076 |
+
}
|
4077 |
+
|
4078 |
+
// ----- Look for abort result
|
4079 |
+
if ($v_result == 2) {
|
4080 |
+
// ----- This status is internal and will be changed in 'skipped'
|
4081 |
+
$p_entry['status'] = "aborted";
|
4082 |
+
$v_result = PCLZIP_ERR_USER_ABORTED;
|
4083 |
+
}
|
4084 |
+
|
4085 |
+
// ----- Update the informations
|
4086 |
+
// Only some fields can be modified
|
4087 |
+
$p_entry['filename'] = $v_local_header['filename'];
|
4088 |
+
}
|
4089 |
+
|
4090 |
+
// ----- Trace
|
4091 |
+
|
4092 |
+
// ----- Look if extraction should be done
|
4093 |
+
if ($p_entry['status'] == 'ok') {
|
4094 |
+
|
4095 |
+
// ----- Do the extraction (if not a folder)
|
4096 |
+
if (!(($p_entry['external']&0x00000010)==0x00000010)) {
|
4097 |
+
// ----- Look for not compressed file
|
4098 |
+
if ($p_entry['compressed_size'] == $p_entry['size']) {
|
4099 |
+
|
4100 |
+
// ----- Read the file in a buffer (one shot)
|
4101 |
+
$v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
|
4102 |
+
|
4103 |
+
// ----- Send the file to the output
|
4104 |
+
echo $v_buffer;
|
4105 |
+
unset($v_buffer);
|
4106 |
+
}
|
4107 |
+
else {
|
4108 |
+
|
4109 |
+
// ----- Read the compressed file in a buffer (one shot)
|
4110 |
+
$v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
|
4111 |
+
|
4112 |
+
// ----- Decompress the file
|
4113 |
+
$v_file_content = gzinflate($v_buffer);
|
4114 |
+
unset($v_buffer);
|
4115 |
+
|
4116 |
+
// ----- Send the file to the output
|
4117 |
+
echo $v_file_content;
|
4118 |
+
unset($v_file_content);
|
4119 |
+
}
|
4120 |
+
}
|
4121 |
+
}
|
4122 |
+
|
4123 |
+
// ----- Change abort status
|
4124 |
+
if ($p_entry['status'] == "aborted") {
|
4125 |
+
$p_entry['status'] = "skipped";
|
4126 |
+
}
|
4127 |
+
|
4128 |
+
// ----- Look for post-extract callback
|
4129 |
+
elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
|
4130 |
+
|
4131 |
+
// ----- Generate a local information
|
4132 |
+
$v_local_header = array();
|
4133 |
+
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
|
4134 |
+
|
4135 |
+
// ----- Call the callback
|
4136 |
+
// Here I do not use call_user_func() because I need to send a reference to the
|
4137 |
+
// header.
|
4138 |
+
// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
|
4139 |
+
$v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
|
4140 |
+
|
4141 |
+
// ----- Look for abort result
|
4142 |
+
if ($v_result == 2) {
|
4143 |
+
$v_result = PCLZIP_ERR_USER_ABORTED;
|
4144 |
+
}
|
4145 |
+
}
|
4146 |
+
|
4147 |
+
return $v_result;
|
4148 |
+
}
|
4149 |
+
// --------------------------------------------------------------------------------
|
4150 |
+
|
4151 |
+
// --------------------------------------------------------------------------------
|
4152 |
+
// Function : privExtractFileAsString()
|
4153 |
+
// Description :
|
4154 |
+
// Parameters :
|
4155 |
+
// Return Values :
|
4156 |
+
// --------------------------------------------------------------------------------
|
4157 |
+
function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)
|
4158 |
+
{
|
4159 |
+
$v_result=1;
|
4160 |
+
|
4161 |
+
// ----- Read the file header
|
4162 |
+
$v_header = array();
|
4163 |
+
if (($v_result = $this->privReadFileHeader($v_header)) != 1)
|
4164 |
+
{
|
4165 |
+
// ----- Return
|
4166 |
+
return $v_result;
|
4167 |
+
}
|
4168 |
+
|
4169 |
+
|
4170 |
+
// ----- Check that the file header is coherent with $p_entry info
|
4171 |
+
if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
|
4172 |
+
// TBC
|
4173 |
+
}
|
4174 |
+
|
4175 |
+
// ----- Look for pre-extract callback
|
4176 |
+
if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
|
4177 |
+
|
4178 |
+
// ----- Generate a local information
|
4179 |
+
$v_local_header = array();
|
4180 |
+
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
|
4181 |
+
|
4182 |
+
// ----- Call the callback
|
4183 |
+
// Here I do not use call_user_func() because I need to send a reference to the
|
4184 |
+
// header.
|
4185 |
+
// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
|
4186 |
+
$v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
|
4187 |
+
if ($v_result == 0) {
|
4188 |
+
// ----- Change the file status
|
4189 |
+
$p_entry['status'] = "skipped";
|
4190 |
+
$v_result = 1;
|
4191 |
+
}
|
4192 |
+
|
4193 |
+
// ----- Look for abort result
|
4194 |
+
if ($v_result == 2) {
|
4195 |
+
// ----- This status is internal and will be changed in 'skipped'
|
4196 |
+
$p_entry['status'] = "aborted";
|
4197 |
+
$v_result = PCLZIP_ERR_USER_ABORTED;
|
4198 |
+
}
|
4199 |
+
|
4200 |
+
// ----- Update the informations
|
4201 |
+
// Only some fields can be modified
|
4202 |
+
$p_entry['filename'] = $v_local_header['filename'];
|
4203 |
+
}
|
4204 |
+
|
4205 |
+
|
4206 |
+
// ----- Look if extraction should be done
|
4207 |
+
if ($p_entry['status'] == 'ok') {
|
4208 |
+
|
4209 |
+
// ----- Do the extraction (if not a folder)
|
4210 |
+
if (!(($p_entry['external']&0x00000010)==0x00000010)) {
|
4211 |
+
// ----- Look for not compressed file
|
4212 |
+
// if ($p_entry['compressed_size'] == $p_entry['size'])
|
4213 |
+
if ($p_entry['compression'] == 0) {
|
4214 |
+
|
4215 |
+
// ----- Reading the file
|
4216 |
+
$p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
|
4217 |
+
}
|
4218 |
+
else {
|
4219 |
+
|
4220 |
+
// ----- Reading the file
|
4221 |
+
$v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
|
4222 |
+
|
4223 |
+
// ----- Decompress the file
|
4224 |
+
if (($p_string = @gzinflate($v_data)) === FALSE) {
|
4225 |
+
// TBC
|
4226 |
+
}
|
4227 |
+
}
|
4228 |
+
|
4229 |
+
// ----- Trace
|
4230 |
+
}
|
4231 |
+
else {
|
4232 |
+
// TBC : error : can not extract a folder in a string
|
4233 |
+
}
|
4234 |
+
|
4235 |
+
}
|
4236 |
+
|
4237 |
+
// ----- Change abort status
|
4238 |
+
if ($p_entry['status'] == "aborted") {
|
4239 |
+
$p_entry['status'] = "skipped";
|
4240 |
+
}
|
4241 |
+
|
4242 |
+
// ----- Look for post-extract callback
|
4243 |
+
elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
|
4244 |
+
|
4245 |
+
// ----- Generate a local information
|
4246 |
+
$v_local_header = array();
|
4247 |
+
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
|
4248 |
+
|
4249 |
+
// ----- Swap the content to header
|
4250 |
+
$v_local_header['content'] = $p_string;
|
4251 |
+
$p_string = '';
|
4252 |
+
|
4253 |
+
// ----- Call the callback
|
4254 |
+
// Here I do not use call_user_func() because I need to send a reference to the
|
4255 |
+
// header.
|
4256 |
+
// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
|
4257 |
+
$v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
|
4258 |
+
|
4259 |
+
// ----- Swap back the content to header
|
4260 |
+
$p_string = $v_local_header['content'];
|
4261 |
+
unset($v_local_header['content']);
|
4262 |
+
|
4263 |
+
// ----- Look for abort result
|
4264 |
+
if ($v_result == 2) {
|
4265 |
+
$v_result = PCLZIP_ERR_USER_ABORTED;
|
4266 |
+
}
|
4267 |
+
}
|
4268 |
+
|
4269 |
+
// ----- Return
|
4270 |
+
return $v_result;
|
4271 |
+
}
|
4272 |
+
// --------------------------------------------------------------------------------
|
4273 |
+
|
4274 |
+
// --------------------------------------------------------------------------------
|
4275 |
+
// Function : privReadFileHeader()
|
4276 |
+
// Description :
|
4277 |
+
// Parameters :
|
4278 |
+
// Return Values :
|
4279 |
+
// --------------------------------------------------------------------------------
|
4280 |
+
function privReadFileHeader(&$p_header)
|
4281 |
+
{
|
4282 |
+
$v_result=1;
|
4283 |
+
|
4284 |
+
// ----- Read the 4 bytes signature
|
4285 |
+
$v_binary_data = @fread($this->zip_fd, 4);
|
4286 |
+
$v_data = unpack('Vid', $v_binary_data);
|
4287 |
+
|
4288 |
+
// ----- Check signature
|
4289 |
+
if ($v_data['id'] != 0x04034b50)
|
4290 |
+
{
|
4291 |
+
|
4292 |
+
// ----- Error log
|
4293 |
+
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
|
4294 |
+
|
4295 |
+
// ----- Return
|
4296 |
+
return PclZip::errorCode();
|
4297 |
+
}
|
4298 |
+
|
4299 |
+
// ----- Read the first 42 bytes of the header
|
4300 |
+
$v_binary_data = fread($this->zip_fd, 26);
|
4301 |
+
|
4302 |
+
// ----- Look for invalid block size
|
4303 |
+
if (strlen($v_binary_data) != 26)
|
4304 |
+
{
|
4305 |
+
$p_header['filename'] = "";
|
4306 |
+
$p_header['status'] = "invalid_header";
|
4307 |
+
|
4308 |
+
// ----- Error log
|
4309 |
+
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
|
4310 |
+
|
4311 |
+
// ----- Return
|
4312 |
+
return PclZip::errorCode();
|
4313 |
+
}
|
4314 |
+
|
4315 |
+
// ----- Extract the values
|
4316 |
+
$v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
|
4317 |
+
|
4318 |
+
// ----- Get filename
|
4319 |
+
$p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
|
4320 |
+
|
4321 |
+
// ----- Get extra_fields
|
4322 |
+
if ($v_data['extra_len'] != 0) {
|
4323 |
+
$p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
|
4324 |
+
}
|
4325 |
+
else {
|
4326 |
+
$p_header['extra'] = '';
|
4327 |
+
}
|
4328 |
+
|
4329 |
+
// ----- Extract properties
|
4330 |
+
$p_header['version_extracted'] = $v_data['version'];
|
4331 |
+
$p_header['compression'] = $v_data['compression'];
|
4332 |
+
$p_header['size'] = $v_data['size'];
|
4333 |
+
$p_header['compressed_size'] = $v_data['compressed_size'];
|
4334 |
+
$p_header['crc'] = $v_data['crc'];
|
4335 |
+
$p_header['flag'] = $v_data['flag'];
|
4336 |
+
$p_header['filename_len'] = $v_data['filename_len'];
|
4337 |
+
|
4338 |
+
// ----- Recuperate date in UNIX format
|
4339 |
+
$p_header['mdate'] = $v_data['mdate'];
|
4340 |
+
$p_header['mtime'] = $v_data['mtime'];
|
4341 |
+
if ($p_header['mdate'] && $p_header['mtime'])
|
4342 |
+
{
|
4343 |
+
// ----- Extract time
|
4344 |
+
$v_hour = ($p_header['mtime'] & 0xF800) >> 11;
|
4345 |
+
$v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
|
4346 |
+
$v_seconde = ($p_header['mtime'] & 0x001F)*2;
|
4347 |
+
|
4348 |
+
// ----- Extract date
|
4349 |
+
$v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
|
4350 |
+
$v_month = ($p_header['mdate'] & 0x01E0) >> 5;
|
4351 |
+
$v_day = $p_header['mdate'] & 0x001F;
|
4352 |
+
|
4353 |
+
// ----- Get UNIX date format
|
4354 |
+
$p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
|
4355 |
+
|
4356 |
+
}
|
4357 |
+
else
|
4358 |
+
{
|
4359 |
+
$p_header['mtime'] = time();
|
4360 |
+
}
|
4361 |
+
|
4362 |
+
// TBC
|
4363 |
+
//for(reset($v_data); $key = key($v_data); next($v_data)) {
|
4364 |
+
//}
|
4365 |
+
|
4366 |
+
// ----- Set the stored filename
|
4367 |
+
$p_header['stored_filename'] = $p_header['filename'];
|
4368 |
+
|
4369 |
+
// ----- Set the status field
|
4370 |
+
$p_header['status'] = "ok";
|
4371 |
+
|
4372 |
+
// ----- Return
|
4373 |
+
return $v_result;
|
4374 |
+
}
|
4375 |
+
// --------------------------------------------------------------------------------
|
4376 |
+
|
4377 |
+
// --------------------------------------------------------------------------------
|
4378 |
+
// Function : privReadCentralFileHeader()
|
4379 |
+
// Description :
|
4380 |
+
// Parameters :
|
4381 |
+
// Return Values :
|
4382 |
+
// --------------------------------------------------------------------------------
|
4383 |
+
function privReadCentralFileHeader(&$p_header)
|
4384 |
+
{
|
4385 |
+
$v_result=1;
|
4386 |
+
|
4387 |
+
// ----- Read the 4 bytes signature
|
4388 |
+
$v_binary_data = @fread($this->zip_fd, 4);
|
4389 |
+
$v_data = unpack('Vid', $v_binary_data);
|
4390 |
+
|
4391 |
+
// ----- Check signature
|
4392 |
+
if ($v_data['id'] != 0x02014b50)
|
4393 |
+
{
|
4394 |
+
|
4395 |
+
// ----- Error log
|
4396 |
+
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
|
4397 |
+
|
4398 |
+
// ----- Return
|
4399 |
+
return PclZip::errorCode();
|
4400 |
+
}
|
4401 |
+
|
4402 |
+
// ----- Read the first 42 bytes of the header
|
4403 |
+
$v_binary_data = fread($this->zip_fd, 42);
|
4404 |
+
|
4405 |
+
// ----- Look for invalid block size
|
4406 |
+
if (strlen($v_binary_data) != 42)
|
4407 |
+
{
|
4408 |
+
$p_header['filename'] = "";
|
4409 |
+
$p_header['status'] = "invalid_header";
|
4410 |
+
|
4411 |
+
// ----- Error log
|
4412 |
+
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
|
4413 |
+
|
4414 |
+
// ----- Return
|
4415 |
+
return PclZip::errorCode();
|
4416 |
+
}
|
4417 |
+
|
4418 |
+
// ----- Extract the values
|
4419 |
+
$p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
|
4420 |
+
|
4421 |
+
// ----- Get filename
|
4422 |
+
if ($p_header['filename_len'] != 0)
|
4423 |
+
$p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
|
4424 |
+
else
|
4425 |
+
$p_header['filename'] = '';
|
4426 |
+
|
4427 |
+
// ----- Get extra
|
4428 |
+
if ($p_header['extra_len'] != 0)
|
4429 |
+
$p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
|
4430 |
+
else
|
4431 |
+
$p_header['extra'] = '';
|
4432 |
+
|
4433 |
+
// ----- Get comment
|
4434 |
+
if ($p_header['comment_len'] != 0)
|
4435 |
+
$p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
|
4436 |
+
else
|
4437 |
+
$p_header['comment'] = '';
|
4438 |
+
|
4439 |
+
// ----- Extract properties
|
4440 |
+
|
4441 |
+
// ----- Recuperate date in UNIX format
|
4442 |
+
//if ($p_header['mdate'] && $p_header['mtime'])
|
4443 |
+
// TBC : bug : this was ignoring time with 0/0/0
|
4444 |
+
if (1)
|
4445 |
+
{
|
4446 |
+
// ----- Extract time
|
4447 |
+
$v_hour = ($p_header['mtime'] & 0xF800) >> 11;
|
4448 |
+
$v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
|
4449 |
+
$v_seconde = ($p_header['mtime'] & 0x001F)*2;
|
4450 |
+
|
4451 |
+
// ----- Extract date
|
4452 |
+
$v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
|
4453 |
+
$v_month = ($p_header['mdate'] & 0x01E0) >> 5;
|
4454 |
+
$v_day = $p_header['mdate'] & 0x001F;
|
4455 |
+
|
4456 |
+
// ----- Get UNIX date format
|
4457 |
+
$p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
|
4458 |
+
|
4459 |
+
}
|
4460 |
+
else
|
4461 |
+
{
|
4462 |
+
$p_header['mtime'] = time();
|
4463 |
+
}
|
4464 |
+
|
4465 |
+
// ----- Set the stored filename
|
4466 |
+
$p_header['stored_filename'] = $p_header['filename'];
|
4467 |
+
|
4468 |
+
// ----- Set default status to ok
|
4469 |
+
$p_header['status'] = 'ok';
|
4470 |
+
|
4471 |
+
// ----- Look if it is a directory
|
4472 |
+
if (substr($p_header['filename'], -1) == '/') {
|
4473 |
+
//$p_header['external'] = 0x41FF0010;
|
4474 |
+
$p_header['external'] = 0x00000010;
|
4475 |
+
}
|
4476 |
+
|
4477 |
+
|
4478 |
+
// ----- Return
|
4479 |
+
return $v_result;
|
4480 |
+
}
|
4481 |
+
// --------------------------------------------------------------------------------
|
4482 |
+
|
4483 |
+
// --------------------------------------------------------------------------------
|
4484 |
+
// Function : privCheckFileHeaders()
|
4485 |
+
// Description :
|
4486 |
+
// Parameters :
|
4487 |
+
// Return Values :
|
4488 |
+
// 1 on success,
|
4489 |
+
// 0 on error;
|
4490 |
+
// --------------------------------------------------------------------------------
|
4491 |
+
function privCheckFileHeaders(&$p_local_header, &$p_central_header)
|
4492 |
+
{
|
4493 |
+
$v_result=1;
|
4494 |
+
|
4495 |
+
// ----- Check the static values
|
4496 |
+
// TBC
|
4497 |
+
if ($p_local_header['filename'] != $p_central_header['filename']) {
|
4498 |
+
}
|
4499 |
+
if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
|
4500 |
+
}
|
4501 |
+
if ($p_local_header['flag'] != $p_central_header['flag']) {
|
4502 |
+
}
|
4503 |
+
if ($p_local_header['compression'] != $p_central_header['compression']) {
|
4504 |
+
}
|
4505 |
+
if ($p_local_header['mtime'] != $p_central_header['mtime']) {
|
4506 |
+
}
|
4507 |
+
if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
|
4508 |
+
}
|
4509 |
+
|
4510 |
+
// ----- Look for flag bit 3
|
4511 |
+
if (($p_local_header['flag'] & 8) == 8) {
|
4512 |
+
$p_local_header['size'] = $p_central_header['size'];
|
4513 |
+
$p_local_header['compressed_size'] = $p_central_header['compressed_size'];
|
4514 |
+
$p_local_header['crc'] = $p_central_header['crc'];
|
4515 |
+
}
|
4516 |
+
|
4517 |
+
// ----- Return
|
4518 |
+
return $v_result;
|
4519 |
+
}
|
4520 |
+
// --------------------------------------------------------------------------------
|
4521 |
+
|
4522 |
+
// --------------------------------------------------------------------------------
|
4523 |
+
// Function : privReadEndCentralDir()
|
4524 |
+
// Description :
|
4525 |
+
// Parameters :
|
4526 |
+
// Return Values :
|
4527 |
+
// --------------------------------------------------------------------------------
|
4528 |
+
function privReadEndCentralDir(&$p_central_dir)
|
4529 |
+
{
|
4530 |
+
$v_result=1;
|
4531 |
+
|
4532 |
+
// ----- Go to the end of the zip file
|
4533 |
+
$v_size = filesize($this->zipname);
|
4534 |
+
@fseek($this->zip_fd, $v_size);
|
4535 |
+
if (@ftell($this->zip_fd) != $v_size)
|
4536 |
+
{
|
4537 |
+
// ----- Error log
|
4538 |
+
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
|
4539 |
+
|
4540 |
+
// ----- Return
|
4541 |
+
return PclZip::errorCode();
|
4542 |
+
}
|
4543 |
+
|
4544 |
+
// ----- First try : look if this is an archive with no commentaries (most of the time)
|
4545 |
+
// in this case the end of central dir is at 22 bytes of the file end
|
4546 |
+
$v_found = 0;
|
4547 |
+
if ($v_size > 26) {
|
4548 |
+
@fseek($this->zip_fd, $v_size-22);
|
4549 |
+
if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
|
4550 |
+
{
|
4551 |
+
// ----- Error log
|
4552 |
+
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
|
4553 |
+
|
4554 |
+
// ----- Return
|
4555 |
+
return PclZip::errorCode();
|
4556 |
+
}
|
4557 |
+
|
4558 |
+
// ----- Read for bytes
|
4559 |
+
$v_binary_data = @fread($this->zip_fd, 4);
|
4560 |
+
$v_data = @unpack('Vid', $v_binary_data);
|
4561 |
+
|
4562 |
+
// ----- Check signature
|
4563 |
+
if ($v_data['id'] == 0x06054b50) {
|
4564 |
+
$v_found = 1;
|
4565 |
+
}
|
4566 |
+
|
4567 |
+
$v_pos = ftell($this->zip_fd);
|
4568 |
+
}
|
4569 |
+
|
4570 |
+
// ----- Go back to the maximum possible size of the Central Dir End Record
|
4571 |
+
if (!$v_found) {
|
4572 |
+
$v_maximum_size = 65557; // 0xFFFF + 22;
|
4573 |
+
if ($v_maximum_size > $v_size)
|
4574 |
+
$v_maximum_size = $v_size;
|
4575 |
+
@fseek($this->zip_fd, $v_size-$v_maximum_size);
|
4576 |
+
if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
|
4577 |
+
{
|
4578 |
+
// ----- Error log
|
4579 |
+
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
|
4580 |
+
|
4581 |
+
// ----- Return
|
4582 |
+
return PclZip::errorCode();
|
4583 |
+
}
|
4584 |
+
|
4585 |
+
// ----- Read byte per byte in order to find the signature
|
4586 |
+
$v_pos = ftell($this->zip_fd);
|
4587 |
+
$v_bytes = 0x00000000;
|
4588 |
+
while ($v_pos < $v_size)
|
4589 |
+
{
|
4590 |
+
// ----- Read a byte
|
4591 |
+
$v_byte = @fread($this->zip_fd, 1);
|
4592 |
+
|
4593 |
+
// ----- Add the byte
|
4594 |
+
//$v_bytes = ($v_bytes << 8) | Ord($v_byte);
|
4595 |
+
// Note we mask the old value down such that once shifted we can never end up with more than a 32bit number
|
4596 |
+
// Otherwise on systems where we have 64bit integers the check below for the magic number will fail.
|
4597 |
+
$v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
|
4598 |
+
|
4599 |
+
// ----- Compare the bytes
|
4600 |
+
if ($v_bytes == 0x504b0506)
|
4601 |
+
{
|
4602 |
+
$v_pos++;
|
4603 |
+
break;
|
4604 |
+
}
|
4605 |
+
|
4606 |
+
$v_pos++;
|
4607 |
+
}
|
4608 |
+
|
4609 |
+
// ----- Look if not found end of central dir
|
4610 |
+
if ($v_pos == $v_size)
|
4611 |
+
{
|
4612 |
+
|
4613 |
+
// ----- Error log
|
4614 |
+
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
|
4615 |
+
|
4616 |
+
// ----- Return
|
4617 |
+
return PclZip::errorCode();
|
4618 |
+
}
|
4619 |
+
}
|
4620 |
+
|
4621 |
+
// ----- Read the first 18 bytes of the header
|
4622 |
+
$v_binary_data = fread($this->zip_fd, 18);
|
4623 |
+
|
4624 |
+
// ----- Look for invalid block size
|
4625 |
+
if (strlen($v_binary_data) != 18)
|
4626 |
+
{
|
4627 |
+
|
4628 |
+
// ----- Error log
|
4629 |
+
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
|
4630 |
+
|
4631 |
+
// ----- Return
|
4632 |
+
return PclZip::errorCode();
|
4633 |
+
}
|
4634 |
+
|
4635 |
+
// ----- Extract the values
|
4636 |
+
$v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
|
4637 |
+
|
4638 |
+
// ----- Check the global size
|
4639 |
+
if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
|
4640 |
+
|
4641 |
+
// ----- Removed in release 2.2 see readme file
|
4642 |
+
// The check of the file size is a little too strict.
|
4643 |
+
// Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
|
4644 |
+
// While decrypted, zip has training 0 bytes
|
4645 |
+
if (0) {
|
4646 |
+
// ----- Error log
|
4647 |
+
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
|
4648 |
+
'The central dir is not at the end of the archive.'
|
4649 |
+
.' Some trailing bytes exists after the archive.');
|
4650 |
+
|
4651 |
+
// ----- Return
|
4652 |
+
return PclZip::errorCode();
|
4653 |
+
}
|
4654 |
+
}
|
4655 |
+
|
4656 |
+
// ----- Get comment
|
4657 |
+
if ($v_data['comment_size'] != 0) {
|
4658 |
+
$p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
|
4659 |
+
}
|
4660 |
+
else
|
4661 |
+
$p_central_dir['comment'] = '';
|
4662 |
+
|
4663 |
+
$p_central_dir['entries'] = $v_data['entries'];
|
4664 |
+
$p_central_dir['disk_entries'] = $v_data['disk_entries'];
|
4665 |
+
$p_central_dir['offset'] = $v_data['offset'];
|
4666 |
+
$p_central_dir['size'] = $v_data['size'];
|
4667 |
+
$p_central_dir['disk'] = $v_data['disk'];
|
4668 |
+
$p_central_dir['disk_start'] = $v_data['disk_start'];
|
4669 |
+
|
4670 |
+
// TBC
|
4671 |
+
//for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
|
4672 |
+
//}
|
4673 |
+
|
4674 |
+
// ----- Return
|
4675 |
+
return $v_result;
|
4676 |
+
}
|
4677 |
+
// --------------------------------------------------------------------------------
|
4678 |
+
|
4679 |
+
// --------------------------------------------------------------------------------
|
4680 |
+
// Function : privDeleteByRule()
|
4681 |
+
// Description :
|
4682 |
+
// Parameters :
|
4683 |
+
// Return Values :
|
4684 |
+
// --------------------------------------------------------------------------------
|
4685 |
+
function privDeleteByRule(&$p_result_list, &$p_options)
|
4686 |
+
{
|
4687 |
+
$v_result=1;
|
4688 |
+
$v_list_detail = array();
|
4689 |
+
|
4690 |
+
// ----- Open the zip file
|
4691 |
+
if (($v_result=$this->privOpenFd('rb')) != 1)
|
4692 |
+
{
|
4693 |
+
// ----- Return
|
4694 |
+
return $v_result;
|
4695 |
+
}
|
4696 |
+
|
4697 |
+
// ----- Read the central directory informations
|
4698 |
+
$v_central_dir = array();
|
4699 |
+
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
|
4700 |
+
{
|
4701 |
+
$this->privCloseFd();
|
4702 |
+
return $v_result;
|
4703 |
+
}
|
4704 |
+
|
4705 |
+
// ----- Go to beginning of File
|
4706 |
+
@rewind($this->zip_fd);
|
4707 |
+
|
4708 |
+
// ----- Scan all the files
|
4709 |
+
// ----- Start at beginning of Central Dir
|
4710 |
+
$v_pos_entry = $v_central_dir['offset'];
|
4711 |
+
@rewind($this->zip_fd);
|
4712 |
+
if (@fseek($this->zip_fd, $v_pos_entry))
|
4713 |
+
{
|
4714 |
+
// ----- Close the zip file
|
4715 |
+
$this->privCloseFd();
|
4716 |
+
|
4717 |
+
// ----- Error log
|
4718 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
|
4719 |
+
|
4720 |
+
// ----- Return
|
4721 |
+
return PclZip::errorCode();
|
4722 |
+
}
|
4723 |
+
|
4724 |
+
// ----- Read each entry
|
4725 |
+
$v_header_list = array();
|
4726 |
+
$j_start = 0;
|
4727 |
+
for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
|
4728 |
+
{
|
4729 |
+
|
4730 |
+
// ----- Read the file header
|
4731 |
+
$v_header_list[$v_nb_extracted] = array();
|
4732 |
+
if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
|
4733 |
+
{
|
4734 |
+
// ----- Close the zip file
|
4735 |
+
$this->privCloseFd();
|
4736 |
+
|
4737 |
+
return $v_result;
|
4738 |
+
}
|
4739 |
+
|
4740 |
+
|
4741 |
+
// ----- Store the index
|
4742 |
+
$v_header_list[$v_nb_extracted]['index'] = $i;
|
4743 |
+
|
4744 |
+
// ----- Look for the specific extract rules
|
4745 |
+
$v_found = false;
|
4746 |
+
|
4747 |
+
// ----- Look for extract by name rule
|
4748 |
+
if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
|
4749 |
+
&& ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
|
4750 |
+
|
4751 |
+
// ----- Look if the filename is in the list
|
4752 |
+
for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
|
4753 |
+
|
4754 |
+
// ----- Look for a directory
|
4755 |
+
if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
|
4756 |
+
|
4757 |
+
// ----- Look if the directory is in the filename path
|
4758 |
+
if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
|
4759 |
+
&& (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
|
4760 |
+
$v_found = true;
|
4761 |
+
}
|
4762 |
+
elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
|
4763 |
+
&& ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
|
4764 |
+
$v_found = true;
|
4765 |
+
}
|
4766 |
+
}
|
4767 |
+
// ----- Look for a filename
|
4768 |
+
elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
|
4769 |
+
$v_found = true;
|
4770 |
+
}
|
4771 |
+
}
|
4772 |
+
}
|
4773 |
+
|
4774 |
+
// ----- Look for extract by ereg rule
|
4775 |
+
// ereg() is deprecated with PHP 5.3
|
4776 |
+
/*
|
4777 |
+
else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
|
4778 |
+
&& ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
|
4779 |
+
|
4780 |
+
if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
|
4781 |
+
$v_found = true;
|
4782 |
+
}
|
4783 |
+
}
|
4784 |
+
*/
|
4785 |
+
|
4786 |
+
// ----- Look for extract by preg rule
|
4787 |
+
else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
|
4788 |
+
&& ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
|
4789 |
+
|
4790 |
+
if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
|
4791 |
+
$v_found = true;
|
4792 |
+
}
|
4793 |
+
}
|
4794 |
+
|
4795 |
+
// ----- Look for extract by index rule
|
4796 |
+
else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
|
4797 |
+
&& ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
|
4798 |
+
|
4799 |
+
// ----- Look if the index is in the list
|
4800 |
+
for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
|
4801 |
+
|
4802 |
+
if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
|
4803 |
+
$v_found = true;
|
4804 |
+
}
|
4805 |
+
if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
|
4806 |
+
$j_start = $j+1;
|
4807 |
+
}
|
4808 |
+
|
4809 |
+
if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
|
4810 |
+
break;
|
4811 |
+
}
|
4812 |
+
}
|
4813 |
+
}
|
4814 |
+
else {
|
4815 |
+
$v_found = true;
|
4816 |
+
}
|
4817 |
+
|
4818 |
+
// ----- Look for deletion
|
4819 |
+
if ($v_found)
|
4820 |
+
{
|
4821 |
+
unset($v_header_list[$v_nb_extracted]);
|
4822 |
+
}
|
4823 |
+
else
|
4824 |
+
{
|
4825 |
+
$v_nb_extracted++;
|
4826 |
+
}
|
4827 |
+
}
|
4828 |
+
|
4829 |
+
// ----- Look if something need to be deleted
|
4830 |
+
if ($v_nb_extracted > 0) {
|
4831 |
+
|
4832 |
+
// ----- Creates a temporay file
|
4833 |
+
$v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
|
4834 |
+
|
4835 |
+
// ----- Creates a temporary zip archive
|
4836 |
+
$v_temp_zip = new PclZip($v_zip_temp_name);
|
4837 |
+
|
4838 |
+
// ----- Open the temporary zip file in write mode
|
4839 |
+
if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
|
4840 |
+
$this->privCloseFd();
|
4841 |
+
|
4842 |
+
// ----- Return
|
4843 |
+
return $v_result;
|
4844 |
+
}
|
4845 |
+
|
4846 |
+
// ----- Look which file need to be kept
|
4847 |
+
for ($i=0; $i<sizeof($v_header_list); $i++) {
|
4848 |
+
|
4849 |
+
// ----- Calculate the position of the header
|
4850 |
+
@rewind($this->zip_fd);
|
4851 |
+
if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {
|
4852 |
+
// ----- Close the zip file
|
4853 |
+
$this->privCloseFd();
|
4854 |
+
$v_temp_zip->privCloseFd();
|
4855 |
+
@unlink($v_zip_temp_name);
|
4856 |
+
|
4857 |
+
// ----- Error log
|
4858 |
+
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
|
4859 |
+
|
4860 |
+
// ----- Return
|
4861 |
+
return PclZip::errorCode();
|
4862 |
+
}
|
4863 |
+
|
4864 |
+
// ----- Read the file header
|
4865 |
+
$v_local_header = array();
|
4866 |
+
if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
|
4867 |
+
// ----- Close the zip file
|
4868 |
+
$this->privCloseFd();
|
4869 |
+
$v_temp_zip->privCloseFd();
|
4870 |
+
@unlink($v_zip_temp_name);
|
4871 |
+
|
4872 |
+
// ----- Return
|
4873 |
+
return $v_result;
|
4874 |
+
}
|
4875 |
+
|
4876 |
+
// ----- Check that local file header is same as central file header
|
4877 |
+
if ($this->privCheckFileHeaders($v_local_header,
|
4878 |
+
$v_header_list[$i]) != 1) {
|
4879 |
+
// TBC
|
4880 |
+
}
|
4881 |
+
unset($v_local_header);
|
4882 |
+
|
4883 |
+
// ----- Write the file header
|
4884 |
+
if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
|
4885 |
+
// ----- Close the zip file
|
4886 |
+
$this->privCloseFd();
|
4887 |
+
$v_temp_zip->privCloseFd();
|
4888 |
+
@unlink($v_zip_temp_name);
|
4889 |
+
|
4890 |
+
// ----- Return
|
4891 |
+
return $v_result;
|
4892 |
+
}
|
4893 |
+
|
4894 |
+
// ----- Read/write the data block
|
4895 |
+
if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
|
4896 |
+
// ----- Close the zip file
|
4897 |
+
$this->privCloseFd();
|
4898 |
+
$v_temp_zip->privCloseFd();
|
4899 |
+
@unlink($v_zip_temp_name);
|
4900 |
+
|
4901 |
+
// ----- Return
|
4902 |
+
return $v_result;
|
4903 |
+
}
|
4904 |
+
}
|
4905 |
+
|
4906 |
+
// ----- Store the offset of the central dir
|
4907 |
+
$v_offset = @ftell($v_temp_zip->zip_fd);
|
4908 |
+
|
4909 |
+
// ----- Re-Create the Central Dir files header
|
4910 |
+
for ($i=0; $i<sizeof($v_header_list); $i++) {
|
4911 |
+
// ----- Create the file header
|
4912 |
+
if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
|
4913 |
+
$v_temp_zip->privCloseFd();
|
4914 |
+
$this->privCloseFd();
|
4915 |
+
@unlink($v_zip_temp_name);
|
4916 |
+
|
4917 |
+
// ----- Return
|
4918 |
+
return $v_result;
|
4919 |
+
}
|
4920 |
+
|
4921 |
+
// ----- Transform the header to a 'usable' info
|
4922 |
+
$v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
|
4923 |
+
}
|
4924 |
+
|
4925 |
+
|
4926 |
+
// ----- Zip file comment
|
4927 |
+
$v_comment = '';
|
4928 |
+
if (isset($p_options[PCLZIP_OPT_COMMENT])) {
|
4929 |
+
$v_comment = $p_options[PCLZIP_OPT_COMMENT];
|
4930 |
+
}
|
4931 |
+
|
4932 |
+
// ----- Calculate the size of the central header
|
4933 |
+
$v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
|
4934 |
+
|
4935 |
+
// ----- Create the central dir footer
|
4936 |
+
if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
|
4937 |
+
// ----- Reset the file list
|
4938 |
+
unset($v_header_list);
|
4939 |
+
$v_temp_zip->privCloseFd();
|
4940 |
+
$this->privCloseFd();
|
4941 |
+
@unlink($v_zip_temp_name);
|
4942 |
+
|
4943 |
+
// ----- Return
|
4944 |
+
return $v_result;
|
4945 |
+
}
|
4946 |
+
|
4947 |
+
// ----- Close
|
4948 |
+
$v_temp_zip->privCloseFd();
|
4949 |
+
$this->privCloseFd();
|
4950 |
+
|
4951 |
+
// ----- Delete the zip file
|
4952 |
+
// TBC : I should test the result ...
|
4953 |
+
@unlink($this->zipname);
|
4954 |
+
|
4955 |
+
// ----- Rename the temporary file
|
4956 |
+
// TBC : I should test the result ...
|
4957 |
+
//@rename($v_zip_temp_name, $this->zipname);
|
4958 |
+
PclZipUtilRename($v_zip_temp_name, $this->zipname);
|
4959 |
+
|
4960 |
+
// ----- Destroy the temporary archive
|
4961 |
+
unset($v_temp_zip);
|
4962 |
+
}
|
4963 |
+
|
4964 |
+
// ----- Remove every files : reset the file
|
4965 |
+
else if ($v_central_dir['entries'] != 0) {
|
4966 |
+
$this->privCloseFd();
|
4967 |
+
|
4968 |
+
if (($v_result = $this->privOpenFd('wb')) != 1) {
|
4969 |
+
return $v_result;
|
4970 |
+
}
|
4971 |
+
|
4972 |
+
if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
|
4973 |
+
return $v_result;
|
4974 |
+
}
|
4975 |
+
|
4976 |
+
$this->privCloseFd();
|
4977 |
+
}
|
4978 |
+
|
4979 |
+
// ----- Return
|
4980 |
+
return $v_result;
|
4981 |
+
}
|
4982 |
+
// --------------------------------------------------------------------------------
|
4983 |
+
|
4984 |
+
// --------------------------------------------------------------------------------
|
4985 |
+
// Function : privDirCheck()
|
4986 |
+
// Description :
|
4987 |
+
// Check if a directory exists, if not it creates it and all the parents directory
|
4988 |
+
// which may be useful.
|
4989 |
+
// Parameters :
|
4990 |
+
// $p_dir : Directory path to check.
|
4991 |
+
// Return Values :
|
4992 |
+
// 1 : OK
|
4993 |
+
// -1 : Unable to create directory
|
4994 |
+
// --------------------------------------------------------------------------------
|
4995 |
+
function privDirCheck($p_dir, $p_is_dir=false)
|
4996 |
+
{
|
4997 |
+
$v_result = 1;
|
4998 |
+
|
4999 |
+
|
5000 |
+
// ----- Remove the final '/'
|
5001 |
+
if (($p_is_dir) && (substr($p_dir, -1)=='/'))
|
5002 |
+
{
|
5003 |
+
$p_dir = substr($p_dir, 0, strlen($p_dir)-1);
|
5004 |
+
}
|
5005 |
+
|
5006 |
+
// ----- Check the directory availability
|
5007 |
+
if ((is_dir($p_dir)) || ($p_dir == ""))
|
5008 |
+
{
|
5009 |
+
return 1;
|
5010 |
+
}
|
5011 |
+
|
5012 |
+
// ----- Extract parent directory
|
5013 |
+
$p_parent_dir = dirname($p_dir);
|
5014 |
+
|
5015 |
+
// ----- Just a check
|
5016 |
+
if ($p_parent_dir != $p_dir)
|
5017 |
+
{
|
5018 |
+
// ----- Look for parent directory
|
5019 |
+
if ($p_parent_dir != "")
|
5020 |
+
{
|
5021 |
+
if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
|
5022 |
+
{
|
5023 |
+
return $v_result;
|
5024 |
+
}
|
5025 |
+
}
|
5026 |
+
}
|
5027 |
+
|
5028 |
+
// ----- Create the directory
|
5029 |
+
if (!@mkdir($p_dir, 0777))
|
5030 |
+
{
|
5031 |
+
// ----- Error log
|
5032 |
+
PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
|
5033 |
+
|
5034 |
+
// ----- Return
|
5035 |
+
return PclZip::errorCode();
|
5036 |
+
}
|
5037 |
+
|
5038 |
+
// ----- Return
|
5039 |
+
return $v_result;
|
5040 |
+
}
|
5041 |
+
// --------------------------------------------------------------------------------
|
5042 |
+
|
5043 |
+
// --------------------------------------------------------------------------------
|
5044 |
+
// Function : privMerge()
|
5045 |
+
// Description :
|
5046 |
+
// If $p_archive_to_add does not exist, the function exit with a success result.
|
5047 |
+
// Parameters :
|
5048 |
+
// Return Values :
|
5049 |
+
// --------------------------------------------------------------------------------
|
5050 |
+
function privMerge(&$p_archive_to_add)
|
5051 |
+
{
|
5052 |
+
$v_result=1;
|
5053 |
+
|
5054 |
+
// ----- Look if the archive_to_add exists
|
5055 |
+
if (!is_file($p_archive_to_add->zipname))
|
5056 |
+
{
|
5057 |
+
|
5058 |
+
// ----- Nothing to merge, so merge is a success
|
5059 |
+
$v_result = 1;
|
5060 |
+
|
5061 |
+
// ----- Return
|
5062 |
+
return $v_result;
|
5063 |
+
}
|
5064 |
+
|
5065 |
+
// ----- Look if the archive exists
|
5066 |
+
if (!is_file($this->zipname))
|
5067 |
+
{
|
5068 |
+
|
5069 |
+
// ----- Do a duplicate
|
5070 |
+
$v_result = $this->privDuplicate($p_archive_to_add->zipname);
|
5071 |
+
|
5072 |
+
// ----- Return
|
5073 |
+
return $v_result;
|
5074 |
+
}
|
5075 |
+
|
5076 |
+
// ----- Open the zip file
|
5077 |
+
if (($v_result=$this->privOpenFd('rb')) != 1)
|
5078 |
+
{
|
5079 |
+
// ----- Return
|
5080 |
+
return $v_result;
|
5081 |
+
}
|
5082 |
+
|
5083 |
+
// ----- Read the central directory informations
|
5084 |
+
$v_central_dir = array();
|
5085 |
+
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
|
5086 |
+
{
|
5087 |
+
$this->privCloseFd();
|
5088 |
+
return $v_result;
|
5089 |
+
}
|
5090 |
+
|
5091 |
+
// ----- Go to beginning of File
|
5092 |
+
@rewind($this->zip_fd);
|
5093 |
+
|
5094 |
+
// ----- Open the archive_to_add file
|
5095 |
+
if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
|
5096 |
+
{
|
5097 |
+
$this->privCloseFd();
|
5098 |
+
|
5099 |
+
// ----- Return
|
5100 |
+
return $v_result;
|
5101 |
+
}
|
5102 |
+
|
5103 |
+
// ----- Read the central directory informations
|
5104 |
+
$v_central_dir_to_add = array();
|
5105 |
+
if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
|
5106 |
+
{
|
5107 |
+
$this->privCloseFd();
|
5108 |
+
$p_archive_to_add->privCloseFd();
|
5109 |
+
|
5110 |
+
return $v_result;
|
5111 |
+
}
|
5112 |
+
|
5113 |
+
// ----- Go to beginning of File
|
5114 |
+
@rewind($p_archive_to_add->zip_fd);
|
5115 |
+
|
5116 |
+
// ----- Creates a temporay file
|
5117 |
+
$v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
|
5118 |
+
|
5119 |
+
// ----- Open the temporary file in write mode
|
5120 |
+
if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
|
5121 |
+
{
|
5122 |
+
$this->privCloseFd();
|
5123 |
+
$p_archive_to_add->privCloseFd();
|
5124 |
+
|
5125 |
+
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
|
5126 |
+
|
5127 |
+
// ----- Return
|
5128 |
+
return PclZip::errorCode();
|
5129 |
+
}
|
5130 |
+
|
5131 |
+
// ----- Copy the files from the archive to the temporary file
|
5132 |
+
// TBC : Here I should better append the file and go back to erase the central dir
|
5133 |
+
$v_size = $v_central_dir['offset'];
|
5134 |
+
while ($v_size != 0)
|
5135 |
+
{
|
5136 |
+
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
|
5137 |
+
$v_buffer = fread($this->zip_fd, $v_read_size);
|
5138 |
+
@fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
|
5139 |
+
$v_size -= $v_read_size;
|
5140 |
+
}
|
5141 |
+
|
5142 |
+
// ----- Copy the files from the archive_to_add into the temporary file
|
5143 |
+
$v_size = $v_central_dir_to_add['offset'];
|
5144 |
+
while ($v_size != 0)
|
5145 |
+
{
|
5146 |
+
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
|
5147 |
+
$v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
|
5148 |
+
@fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
|
5149 |
+
$v_size -= $v_read_size;
|
5150 |
+
}
|
5151 |
+
|
5152 |
+
// ----- Store the offset of the central dir
|
5153 |
+
$v_offset = @ftell($v_zip_temp_fd);
|
5154 |
+
|
5155 |
+
// ----- Copy the block of file headers from the old archive
|
5156 |
+
$v_size = $v_central_dir['size'];
|
5157 |
+
while ($v_size != 0)
|
5158 |
+
{
|
5159 |
+
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
|
5160 |
+
$v_buffer = @fread($this->zip_fd, $v_read_size);
|
5161 |
+
@fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
|
5162 |
+
$v_size -= $v_read_size;
|
5163 |
+
}
|
5164 |
+
|
5165 |
+
// ----- Copy the block of file headers from the archive_to_add
|
5166 |
+
$v_size = $v_central_dir_to_add['size'];
|
5167 |
+
while ($v_size != 0)
|
5168 |
+
{
|
5169 |
+
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
|
5170 |
+
$v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
|
5171 |
+
@fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
|
5172 |
+
$v_size -= $v_read_size;
|
5173 |
+
}
|
5174 |
+
|
5175 |
+
// ----- Merge the file comments
|
5176 |
+
$v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
|
5177 |
+
|
5178 |
+
// ----- Calculate the size of the (new) central header
|
5179 |
+
$v_size = @ftell($v_zip_temp_fd)-$v_offset;
|
5180 |
+
|
5181 |
+
// ----- Swap the file descriptor
|
5182 |
+
// Here is a trick : I swap the temporary fd with the zip fd, in order to use
|
5183 |
+
// the following methods on the temporary fil and not the real archive fd
|
5184 |
+
$v_swap = $this->zip_fd;
|
5185 |
+
$this->zip_fd = $v_zip_temp_fd;
|
5186 |
+
$v_zip_temp_fd = $v_swap;
|
5187 |
+
|
5188 |
+
// ----- Create the central dir footer
|
5189 |
+
if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
|
5190 |
+
{
|
5191 |
+
$this->privCloseFd();
|
5192 |
+
$p_archive_to_add->privCloseFd();
|
5193 |
+
@fclose($v_zip_temp_fd);
|
5194 |
+
$this->zip_fd = null;
|
5195 |
+
|
5196 |
+
// ----- Reset the file list
|
5197 |
+
unset($v_header_list);
|
5198 |
+
|
5199 |
+
// ----- Return
|
5200 |
+
return $v_result;
|
5201 |
+
}
|
5202 |
+
|
5203 |
+
// ----- Swap back the file descriptor
|
5204 |
+
$v_swap = $this->zip_fd;
|
5205 |
+
$this->zip_fd = $v_zip_temp_fd;
|
5206 |
+
$v_zip_temp_fd = $v_swap;
|
5207 |
+
|
5208 |
+
// ----- Close
|
5209 |
+
$this->privCloseFd();
|
5210 |
+
$p_archive_to_add->privCloseFd();
|
5211 |
+
|
5212 |
+
// ----- Close the temporary file
|
5213 |
+
@fclose($v_zip_temp_fd);
|
5214 |
+
|
5215 |
+
// ----- Delete the zip file
|
5216 |
+
// TBC : I should test the result ...
|
5217 |
+
@unlink($this->zipname);
|
5218 |
+
|
5219 |
+
// ----- Rename the temporary file
|
5220 |
+
// TBC : I should test the result ...
|
5221 |
+
//@rename($v_zip_temp_name, $this->zipname);
|
5222 |
+
PclZipUtilRename($v_zip_temp_name, $this->zipname);
|
5223 |
+
|
5224 |
+
// ----- Return
|
5225 |
+
return $v_result;
|
5226 |
+
}
|
5227 |
+
// --------------------------------------------------------------------------------
|
5228 |
+
|
5229 |
+
// --------------------------------------------------------------------------------
|
5230 |
+
// Function : privDuplicate()
|
5231 |
+
// Description :
|
5232 |
+
// Parameters :
|
5233 |
+
// Return Values :
|
5234 |
+
// --------------------------------------------------------------------------------
|
5235 |
+
function privDuplicate($p_archive_filename)
|
5236 |
+
{
|
5237 |
+
$v_result=1;
|
5238 |
+
|
5239 |
+
// ----- Look if the $p_archive_filename exists
|
5240 |
+
if (!is_file($p_archive_filename))
|
5241 |
+
{
|
5242 |
+
|
5243 |
+
// ----- Nothing to duplicate, so duplicate is a success.
|
5244 |
+
$v_result = 1;
|
5245 |
+
|
5246 |
+
// ----- Return
|
5247 |
+
return $v_result;
|
5248 |
+
}
|
5249 |
+
|
5250 |
+
// ----- Open the zip file
|
5251 |
+
if (($v_result=$this->privOpenFd('wb')) != 1)
|
5252 |
+
{
|
5253 |
+
// ----- Return
|
5254 |
+
return $v_result;
|
5255 |
+
}
|
5256 |
+
|
5257 |
+
// ----- Open the temporary file in write mode
|
5258 |
+
if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
|
5259 |
+
{
|
5260 |
+
$this->privCloseFd();
|
5261 |
+
|
5262 |
+
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
|
5263 |
+
|
5264 |
+
// ----- Return
|
5265 |
+
return PclZip::errorCode();
|
5266 |
+
}
|
5267 |
+
|
5268 |
+
// ----- Copy the files from the archive to the temporary file
|
5269 |
+
// TBC : Here I should better append the file and go back to erase the central dir
|
5270 |
+
$v_size = filesize($p_archive_filename);
|
5271 |
+
while ($v_size != 0)
|
5272 |
+
{
|
5273 |
+
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
|
5274 |
+
$v_buffer = fread($v_zip_temp_fd, $v_read_size);
|
5275 |
+
@fwrite($this->zip_fd, $v_buffer, $v_read_size);
|
5276 |
+
$v_size -= $v_read_size;
|
5277 |
+
}
|
5278 |
+
|
5279 |
+
// ----- Close
|
5280 |
+
$this->privCloseFd();
|
5281 |
+
|
5282 |
+
// ----- Close the temporary file
|
5283 |
+
@fclose($v_zip_temp_fd);
|
5284 |
+
|
5285 |
+
// ----- Return
|
5286 |
+
return $v_result;
|
5287 |
+
}
|
5288 |
+
// --------------------------------------------------------------------------------
|
5289 |
+
|
5290 |
+
// --------------------------------------------------------------------------------
|
5291 |
+
// Function : privErrorLog()
|
5292 |
+
// Description :
|
5293 |
+
// Parameters :
|
5294 |
+
// --------------------------------------------------------------------------------
|
5295 |
+
function privErrorLog($p_error_code=0, $p_error_string='')
|
5296 |
+
{
|
5297 |
+
if (PCLZIP_ERROR_EXTERNAL == 1) {
|
5298 |
+
PclError($p_error_code, $p_error_string);
|
5299 |
+
}
|
5300 |
+
else {
|
5301 |
+
$this->error_code = $p_error_code;
|
5302 |
+
$this->error_string = $p_error_string;
|
5303 |
+
}
|
5304 |
+
}
|
5305 |
+
// --------------------------------------------------------------------------------
|
5306 |
+
|
5307 |
+
// --------------------------------------------------------------------------------
|
5308 |
+
// Function : privErrorReset()
|
5309 |
+
// Description :
|
5310 |
+
// Parameters :
|
5311 |
+
// --------------------------------------------------------------------------------
|
5312 |
+
function privErrorReset()
|
5313 |
+
{
|
5314 |
+
if (PCLZIP_ERROR_EXTERNAL == 1) {
|
5315 |
+
PclErrorReset();
|
5316 |
+
}
|
5317 |
+
else {
|
5318 |
+
$this->error_code = 0;
|
5319 |
+
$this->error_string = '';
|
5320 |
+
}
|
5321 |
+
}
|
5322 |
+
// --------------------------------------------------------------------------------
|
5323 |
+
|
5324 |
+
// --------------------------------------------------------------------------------
|
5325 |
+
// Function : privDisableMagicQuotes()
|
5326 |
+
// Description :
|
5327 |
+
// Parameters :
|
5328 |
+
// Return Values :
|
5329 |
+
// --------------------------------------------------------------------------------
|
5330 |
+
function privDisableMagicQuotes()
|
5331 |
+
{
|
5332 |
+
$v_result=1;
|
5333 |
+
|
5334 |
+
// ----- Look if function exists
|
5335 |
+
if ( (!function_exists("get_magic_quotes_runtime"))
|
5336 |
+
|| (!function_exists("set_magic_quotes_runtime"))) {
|
5337 |
+
return $v_result;
|
5338 |
+
}
|
5339 |
+
|
5340 |
+
// ----- Look if already done
|
5341 |
+
if ($this->magic_quotes_status != -1) {
|
5342 |
+
return $v_result;
|
5343 |
+
}
|
5344 |
+
|
5345 |
+
// ----- Get and memorize the magic_quote value
|
5346 |
+
$this->magic_quotes_status = @get_magic_quotes_runtime();
|
5347 |
+
|
5348 |
+
// ----- Disable magic_quotes
|
5349 |
+
if ($this->magic_quotes_status == 1) {
|
5350 |
+
@set_magic_quotes_runtime(0);
|
5351 |
+
}
|
5352 |
+
|
5353 |
+
// ----- Return
|
5354 |
+
return $v_result;
|
5355 |
+
}
|
5356 |
+
// --------------------------------------------------------------------------------
|
5357 |
+
|
5358 |
+
// --------------------------------------------------------------------------------
|
5359 |
+
// Function : privSwapBackMagicQuotes()
|
5360 |
+
// Description :
|
5361 |
+
// Parameters :
|
5362 |
+
// Return Values :
|
5363 |
+
// --------------------------------------------------------------------------------
|
5364 |
+
function privSwapBackMagicQuotes()
|
5365 |
+
{
|
5366 |
+
$v_result=1;
|
5367 |
+
|
5368 |
+
// ----- Look if function exists
|
5369 |
+
if ( (!function_exists("get_magic_quotes_runtime"))
|
5370 |
+
|| (!function_exists("set_magic_quotes_runtime"))) {
|
5371 |
+
return $v_result;
|
5372 |
+
}
|
5373 |
+
|
5374 |
+
// ----- Look if something to do
|
5375 |
+
if ($this->magic_quotes_status != -1) {
|
5376 |
+
return $v_result;
|
5377 |
+
}
|
5378 |
+
|
5379 |
+
// ----- Swap back magic_quotes
|
5380 |
+
if ($this->magic_quotes_status == 1) {
|
5381 |
+
@set_magic_quotes_runtime($this->magic_quotes_status);
|
5382 |
+
}
|
5383 |
+
|
5384 |
+
// ----- Return
|
5385 |
+
return $v_result;
|
5386 |
+
}
|
5387 |
+
// --------------------------------------------------------------------------------
|
5388 |
+
|
5389 |
+
}
|
5390 |
+
// End of class
|
5391 |
+
// --------------------------------------------------------------------------------
|
5392 |
+
|
5393 |
+
// --------------------------------------------------------------------------------
|
5394 |
+
// Function : PclZipUtilPathReduction()
|
5395 |
+
// Description :
|
5396 |
+
// Parameters :
|
5397 |
+
// Return Values :
|
5398 |
+
// --------------------------------------------------------------------------------
|
5399 |
+
function PclZipUtilPathReduction($p_dir)
|
5400 |
+
{
|
5401 |
+
$v_result = "";
|
5402 |
+
|
5403 |
+
// ----- Look for not empty path
|
5404 |
+
if ($p_dir != "") {
|
5405 |
+
// ----- Explode path by directory names
|
5406 |
+
$v_list = explode("/", $p_dir);
|
5407 |
+
|
5408 |
+
// ----- Study directories from last to first
|
5409 |
+
$v_skip = 0;
|
5410 |
+
for ($i=sizeof($v_list)-1; $i>=0; $i--) {
|
5411 |
+
// ----- Look for current path
|
5412 |
+
if ($v_list[$i] == ".") {
|
5413 |
+
// ----- Ignore this directory
|
5414 |
+
// Should be the first $i=0, but no check is done
|
5415 |
+
}
|
5416 |
+
else if ($v_list[$i] == "..") {
|
5417 |
+
$v_skip++;
|
5418 |
+
}
|
5419 |
+
else if ($v_list[$i] == "") {
|
5420 |
+
// ----- First '/' i.e. root slash
|
5421 |
+
if ($i == 0) {
|
5422 |
+
$v_result = "/".$v_result;
|
5423 |
+
if ($v_skip > 0) {
|
5424 |
+
// ----- It is an invalid path, so the path is not modified
|
5425 |
+
// TBC
|
5426 |
+
$v_result = $p_dir;
|
5427 |
+
$v_skip = 0;
|
5428 |
+
}
|
5429 |
+
}
|
5430 |
+
// ----- Last '/' i.e. indicates a directory
|
5431 |
+
else if ($i == (sizeof($v_list)-1)) {
|
5432 |
+
$v_result = $v_list[$i];
|
5433 |
+
}
|
5434 |
+
// ----- Double '/' inside the path
|
5435 |
+
else {
|
5436 |
+
// ----- Ignore only the double '//' in path,
|
5437 |
+
// but not the first and last '/'
|
5438 |
+
}
|
5439 |
+
}
|
5440 |
+
else {
|
5441 |
+
// ----- Look for item to skip
|
5442 |
+
if ($v_skip > 0) {
|
5443 |
+
$v_skip--;
|
5444 |
+
}
|
5445 |
+
else {
|
5446 |
+
$v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
|
5447 |
+
}
|
5448 |
+
}
|
5449 |
+
}
|
5450 |
+
|
5451 |
+
// ----- Look for skip
|
5452 |
+
if ($v_skip > 0) {
|
5453 |
+
while ($v_skip > 0) {
|
5454 |
+
$v_result = '../'.$v_result;
|
5455 |
+
$v_skip--;
|
5456 |
+
}
|
5457 |
+
}
|
5458 |
+
}
|
5459 |
+
|
5460 |
+
// ----- Return
|
5461 |
+
return $v_result;
|
5462 |
+
}
|
5463 |
+
// --------------------------------------------------------------------------------
|
5464 |
+
|
5465 |
+
// --------------------------------------------------------------------------------
|
5466 |
+
// Function : PclZipUtilPathInclusion()
|
5467 |
+
// Description :
|
5468 |
+
// This function indicates if the path $p_path is under the $p_dir tree. Or,
|
5469 |
+
// said in an other way, if the file or sub-dir $p_path is inside the dir
|
5470 |
+
// $p_dir.
|
5471 |
+
// The function indicates also if the path is exactly the same as the dir.
|
5472 |
+
// This function supports path with duplicated '/' like '//', but does not
|
5473 |
+
// support '.' or '..' statements.
|
5474 |
+
// Parameters :
|
5475 |
+
// Return Values :
|
5476 |
+
// 0 if $p_path is not inside directory $p_dir
|
5477 |
+
// 1 if $p_path is inside directory $p_dir
|
5478 |
+
// 2 if $p_path is exactly the same as $p_dir
|
5479 |
+
// --------------------------------------------------------------------------------
|
5480 |
+
function PclZipUtilPathInclusion($p_dir, $p_path)
|
5481 |
+
{
|
5482 |
+
$v_result = 1;
|
5483 |
+
|
5484 |
+
// ----- Look for path beginning by ./
|
5485 |
+
if ( ($p_dir == '.')
|
5486 |
+
|| ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
|
5487 |
+
$p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
|
5488 |
+
}
|
5489 |
+
if ( ($p_path == '.')
|
5490 |
+
|| ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
|
5491 |
+
$p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
|
5492 |
+
}
|
5493 |
+
|
5494 |
+
// ----- Explode dir and path by directory separator
|
5495 |
+
$v_list_dir = explode("/", $p_dir);
|
5496 |
+
$v_list_dir_size = sizeof($v_list_dir);
|
5497 |
+
$v_list_path = explode("/", $p_path);
|
5498 |
+
$v_list_path_size = sizeof($v_list_path);
|
5499 |
+
|
5500 |
+
// ----- Study directories paths
|
5501 |
+
$i = 0;
|
5502 |
+
$j = 0;
|
5503 |
+
while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
|
5504 |
+
|
5505 |
+
// ----- Look for empty dir (path reduction)
|
5506 |
+
if ($v_list_dir[$i] == '') {
|
5507 |
+
$i++;
|
5508 |
+
continue;
|
5509 |
+
}
|
5510 |
+
if ($v_list_path[$j] == '') {
|
5511 |
+
$j++;
|
5512 |
+
continue;
|
5513 |
+
}
|
5514 |
+
|
5515 |
+
// ----- Compare the items
|
5516 |
+
if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) {
|
5517 |
+
$v_result = 0;
|
5518 |
+
}
|
5519 |
+
|
5520 |
+
// ----- Next items
|
5521 |
+
$i++;
|
5522 |
+
$j++;
|
5523 |
+
}
|
5524 |
+
|
5525 |
+
// ----- Look if everything seems to be the same
|
5526 |
+
if ($v_result) {
|
5527 |
+
// ----- Skip all the empty items
|
5528 |
+
while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
|
5529 |
+
while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
|
5530 |
+
|
5531 |
+
if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
|
5532 |
+
// ----- There are exactly the same
|
5533 |
+
$v_result = 2;
|
5534 |
+
}
|
5535 |
+
else if ($i < $v_list_dir_size) {
|
5536 |
+
// ----- The path is shorter than the dir
|
5537 |
+
$v_result = 0;
|
5538 |
+
}
|
5539 |
+
}
|
5540 |
+
|
5541 |
+
// ----- Return
|
5542 |
+
return $v_result;
|
5543 |
+
}
|
5544 |
+
// --------------------------------------------------------------------------------
|
5545 |
+
|
5546 |
+
// --------------------------------------------------------------------------------
|
5547 |
+
// Function : PclZipUtilCopyBlock()
|
5548 |
+
// Description :
|
5549 |
+
// Parameters :
|
5550 |
+
// $p_mode : read/write compression mode
|
5551 |
+
// 0 : src & dest normal
|
5552 |
+
// 1 : src gzip, dest normal
|
5553 |
+
// 2 : src normal, dest gzip
|
5554 |
+
// 3 : src & dest gzip
|
5555 |
+
// Return Values :
|
5556 |
+
// --------------------------------------------------------------------------------
|
5557 |
+
function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
|
5558 |
+
{
|
5559 |
+
$v_result = 1;
|
5560 |
+
|
5561 |
+
if ($p_mode==0)
|
5562 |
+
{
|
5563 |
+
while ($p_size != 0)
|
5564 |
+
{
|
5565 |
+
$v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
|
5566 |
+
$v_buffer = @fread($p_src, $v_read_size);
|
5567 |
+
@fwrite($p_dest, $v_buffer, $v_read_size);
|
5568 |
+
$p_size -= $v_read_size;
|
5569 |
+
}
|
5570 |
+
}
|
5571 |
+
else if ($p_mode==1)
|
5572 |
+
{
|
5573 |
+
while ($p_size != 0)
|
5574 |
+
{
|
5575 |
+
$v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
|
5576 |
+
$v_buffer = @gzread($p_src, $v_read_size);
|
5577 |
+
@fwrite($p_dest, $v_buffer, $v_read_size);
|
5578 |
+
$p_size -= $v_read_size;
|
5579 |
+
}
|
5580 |
+
}
|
5581 |
+
else if ($p_mode==2)
|
5582 |
+
{
|
5583 |
+
while ($p_size != 0)
|
5584 |
+
{
|
5585 |
+
$v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
|
5586 |
+
$v_buffer = @fread($p_src, $v_read_size);
|
5587 |
+
@gzwrite($p_dest, $v_buffer, $v_read_size);
|
5588 |
+
$p_size -= $v_read_size;
|
5589 |
+
}
|
5590 |
+
}
|
5591 |
+
else if ($p_mode==3)
|
5592 |
+
{
|
5593 |
+
while ($p_size != 0)
|
5594 |
+
{
|
5595 |
+
$v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
|
5596 |
+
$v_buffer = @gzread($p_src, $v_read_size);
|
5597 |
+
@gzwrite($p_dest, $v_buffer, $v_read_size);
|
5598 |
+
$p_size -= $v_read_size;
|
5599 |
+
}
|
5600 |
+
}
|
5601 |
+
|
5602 |
+
// ----- Return
|
5603 |
+
return $v_result;
|
5604 |
+
}
|
5605 |
+
// --------------------------------------------------------------------------------
|
5606 |
+
|
5607 |
+
// --------------------------------------------------------------------------------
|
5608 |
+
// Function : PclZipUtilRename()
|
5609 |
+
// Description :
|
5610 |
+
// This function tries to do a simple rename() function. If it fails, it
|
5611 |
+
// tries to copy the $p_src file in a new $p_dest file and then unlink the
|
5612 |
+
// first one.
|
5613 |
+
// Parameters :
|
5614 |
+
// $p_src : Old filename
|
5615 |
+
// $p_dest : New filename
|
5616 |
+
// Return Values :
|
5617 |
+
// 1 on success, 0 on failure.
|
5618 |
+
// --------------------------------------------------------------------------------
|
5619 |
+
function PclZipUtilRename($p_src, $p_dest)
|
5620 |
+
{
|
5621 |
+
$v_result = 1;
|
5622 |
+
|
5623 |
+
// ----- Try to rename the files
|
5624 |
+
if (!@rename($p_src, $p_dest)) {
|
5625 |
+
|
5626 |
+
// ----- Try to copy & unlink the src
|
5627 |
+
if (!@copy($p_src, $p_dest)) {
|
5628 |
+
$v_result = 0;
|
5629 |
+
}
|
5630 |
+
else if (!@unlink($p_src)) {
|
5631 |
+
$v_result = 0;
|
5632 |
+
}
|
5633 |
+
}
|
5634 |
+
|
5635 |
+
// ----- Return
|
5636 |
+
return $v_result;
|
5637 |
+
}
|
5638 |
+
// --------------------------------------------------------------------------------
|
5639 |
+
|
5640 |
+
// --------------------------------------------------------------------------------
|
5641 |
+
// Function : PclZipUtilOptionText()
|
5642 |
+
// Description :
|
5643 |
+
// Translate option value in text. Mainly for debug purpose.
|
5644 |
+
// Parameters :
|
5645 |
+
// $p_option : the option value.
|
5646 |
+
// Return Values :
|
5647 |
+
// The option text value.
|
5648 |
+
// --------------------------------------------------------------------------------
|
5649 |
+
function PclZipUtilOptionText($p_option)
|
5650 |
+
{
|
5651 |
+
|
5652 |
+
$v_list = get_defined_constants();
|
5653 |
+
for (reset($v_list); $v_key = key($v_list); next($v_list)) {
|
5654 |
+
$v_prefix = substr($v_key, 0, 10);
|
5655 |
+
if (( ($v_prefix == 'PCLZIP_OPT')
|
5656 |
+
|| ($v_prefix == 'PCLZIP_CB_')
|
5657 |
+
|| ($v_prefix == 'PCLZIP_ATT'))
|
5658 |
+
&& ($v_list[$v_key] == $p_option)) {
|
5659 |
+
return $v_key;
|
5660 |
+
}
|
5661 |
+
}
|
5662 |
+
|
5663 |
+
$v_result = 'Unknown';
|
5664 |
+
|
5665 |
+
return $v_result;
|
5666 |
+
}
|
5667 |
+
// --------------------------------------------------------------------------------
|
5668 |
+
|
5669 |
+
// --------------------------------------------------------------------------------
|
5670 |
+
// Function : PclZipUtilTranslateWinPath()
|
5671 |
+
// Description :
|
5672 |
+
// Translate windows path by replacing '\' by '/' and optionally removing
|
5673 |
+
// drive letter.
|
5674 |
+
// Parameters :
|
5675 |
+
// $p_path : path to translate.
|
5676 |
+
// $p_remove_disk_letter : true | false
|
5677 |
+
// Return Values :
|
5678 |
+
// The path translated.
|
5679 |
+
// --------------------------------------------------------------------------------
|
5680 |
+
function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
|
5681 |
+
{
|
5682 |
+
if (stristr(php_uname(), 'windows')) {
|
5683 |
+
// ----- Look for potential disk letter
|
5684 |
+
if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
|
5685 |
+
$p_path = substr($p_path, $v_position+1);
|
5686 |
+
}
|
5687 |
+
// ----- Change potential windows directory separator
|
5688 |
+
if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
|
5689 |
+
$p_path = strtr($p_path, '\\', '/');
|
5690 |
+
}
|
5691 |
+
}
|
5692 |
+
return $p_path;
|
5693 |
+
}
|
5694 |
+
// --------------------------------------------------------------------------------
|
5695 |
+
|
5696 |
+
|
5697 |
+
?>
|
models/file/record.php
CHANGED
@@ -22,8 +22,10 @@ class PMXI_File_Record extends PMXI_Model_Record {
|
|
22 |
|
23 |
parent::insert();
|
24 |
|
|
|
|
|
25 |
if (isset($this->id) and ! is_null($file_contents)) {
|
26 |
-
file_put_contents(
|
27 |
}
|
28 |
|
29 |
$list = new PMXI_File_List();
|
@@ -44,7 +46,8 @@ class PMXI_File_Record extends PMXI_Model_Record {
|
|
44 |
parent::update();
|
45 |
|
46 |
if (isset($this->id) and ! is_null($file_contents)) {
|
47 |
-
|
|
|
48 |
}
|
49 |
|
50 |
return $this;
|
@@ -52,7 +55,8 @@ class PMXI_File_Record extends PMXI_Model_Record {
|
|
52 |
|
53 |
public function __isset($field) {
|
54 |
if ('contents' == $field and ! $this->offsetExists($field)) {
|
55 |
-
|
|
|
56 |
}
|
57 |
return parent::__isset($field);
|
58 |
}
|
@@ -60,7 +64,8 @@ class PMXI_File_Record extends PMXI_Model_Record {
|
|
60 |
public function __get($field) {
|
61 |
if ('contents' == $field and ! $this->offsetExists('contents')) {
|
62 |
if (isset($this->contents)) {
|
63 |
-
$
|
|
|
64 |
} else {
|
65 |
$this->contents = NULL;
|
66 |
}
|
@@ -70,7 +75,8 @@ class PMXI_File_Record extends PMXI_Model_Record {
|
|
70 |
|
71 |
public function delete() {
|
72 |
if ($this->id) { // delete history file first
|
73 |
-
$
|
|
|
74 |
is_file($file_name) and unlink($file_name);
|
75 |
}
|
76 |
return parent::delete();
|
22 |
|
23 |
parent::insert();
|
24 |
|
25 |
+
$uploads = wp_upload_dir();
|
26 |
+
|
27 |
if (isset($this->id) and ! is_null($file_contents)) {
|
28 |
+
file_put_contents($uploads['basedir'] . '/wpallimport_history/' . $this->id, $file_contents);
|
29 |
}
|
30 |
|
31 |
$list = new PMXI_File_List();
|
46 |
parent::update();
|
47 |
|
48 |
if (isset($this->id) and ! is_null($file_contents)) {
|
49 |
+
$uploads = wp_upload_dir();
|
50 |
+
file_put_contents($uploads['basedir'] . '/wpallimport_history/' . $this->id, $file_contents);
|
51 |
}
|
52 |
|
53 |
return $this;
|
55 |
|
56 |
public function __isset($field) {
|
57 |
if ('contents' == $field and ! $this->offsetExists($field)) {
|
58 |
+
$uploads = wp_upload_dir();
|
59 |
+
return isset($this->id) and file_exists($uploads['basedir'] . '/wpallimport_history/' . $this->id);
|
60 |
}
|
61 |
return parent::__isset($field);
|
62 |
}
|
64 |
public function __get($field) {
|
65 |
if ('contents' == $field and ! $this->offsetExists('contents')) {
|
66 |
if (isset($this->contents)) {
|
67 |
+
$uploads = wp_upload_dir();
|
68 |
+
$this['contents'] = file_get_contents($uploads['basedir'] . '/wpallimport_history/' . $this->id);
|
69 |
} else {
|
70 |
$this->contents = NULL;
|
71 |
}
|
75 |
|
76 |
public function delete() {
|
77 |
if ($this->id) { // delete history file first
|
78 |
+
$uploads = wp_upload_dir();
|
79 |
+
$file_name = $uploads['basedir'] . '/wpallimport_history/' . $this->id;
|
80 |
is_file($file_name) and unlink($file_name);
|
81 |
}
|
82 |
return parent::delete();
|
models/import/record.php
CHANGED
@@ -6,20 +6,12 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
6 |
* Some pre-processing logic, such as removing control characters from xml to prevent parsing errors
|
7 |
* @param string $xml
|
8 |
*/
|
9 |
-
public static function preprocessXml( & $xml) {
|
10 |
-
//$xml = preg_replace('%\pC(?<!\s)%u', '', $xml); // remove control chars but not white-spacing ones
|
11 |
-
//use HTML::Entities;
|
12 |
|
13 |
-
$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
|
@@ -30,16 +22,15 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
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 |
-
|
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);
|
40 |
$xml_errors = libxml_get_errors();
|
41 |
libxml_clear_errors();
|
42 |
-
if ($xml_errors) {
|
43 |
$error_msg = '<strong>' . __('Invalid XML', 'pmxi_plugin') . '</strong><ul>';
|
44 |
foreach($xml_errors as $error) {
|
45 |
$error_msg .= '<li>';
|
@@ -50,7 +41,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
50 |
$error_msg .= '</li>';
|
51 |
}
|
52 |
$error_msg .= '</ul>';
|
53 |
-
$errors and $errors->add('form-validation', $error_msg);
|
54 |
} else {
|
55 |
return true;
|
56 |
}
|
@@ -65,114 +56,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
65 |
public function __construct($data = array()) {
|
66 |
parent::__construct($data);
|
67 |
$this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'imports');
|
68 |
-
}
|
69 |
-
|
70 |
-
/**
|
71 |
-
* Check whether current import should be perfomed again according to scheduling options
|
72 |
-
*/
|
73 |
-
public function isDue()
|
74 |
-
{
|
75 |
-
if ( ! $this->scheduled or date('YmdHi') <= date('YmdHi', strtotime($this->registered_on))) return false; // scheduling is disabled or the task has been executed this very minute
|
76 |
-
if ('0000-00-00 00:00:00' == $this->registered_on) return true; // never executed but scheduled
|
77 |
-
|
78 |
-
$task = new _PMXI_Import_Record_Cron_Parser($this->scheduled);
|
79 |
-
return $task->isDue($this->registered_on);
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Import all files matched by path
|
84 |
-
* @param callback[optional] $logger Method where progress messages are submmitted
|
85 |
-
* @return PMXI_Import_Record
|
86 |
-
* @chainable
|
87 |
-
*/
|
88 |
-
public function execute($logger = NULL) {
|
89 |
-
$this->set('registered_on', date('Y-m-d H:i:s'))->save(); // update registered_on to indicated that job has been exectured even if no files are going to be imported by the rest of the method
|
90 |
-
|
91 |
-
if ($this->path) {
|
92 |
-
if (in_array($this->type, array('ftp', 'file'))) { // file paths support patterns
|
93 |
-
$logger and call_user_func($logger, __('Reading files for import...', 'pmxi_plugin'));
|
94 |
-
$files = PMXI_Helper::safe_glob($this->path, PMXI_Helper::GLOB_NODIR | PMXI_Helper::GLOB_PATH);
|
95 |
-
$logger and call_user_func($logger, sprintf(_n('%s file found', '%s files found', count($files), 'pmxi_plugin'), count($files)));
|
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'));
|
173 |
-
}
|
174 |
-
return $this;
|
175 |
-
}
|
176 |
|
177 |
/**
|
178 |
* Perform import operation
|
@@ -181,25 +65,18 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
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 |
|
200 |
$tmp_files = array();
|
201 |
// compose records to import
|
202 |
$records = array();
|
|
|
203 |
if ($this->options['is_import_specified']) {
|
204 |
foreach (preg_split('% *, *%', $this->options['import_specified'], -1, PREG_SPLIT_NO_EMPTY) as $chank) {
|
205 |
if (preg_match('%^(\d+)-(\d+)$%', $chank, $mtch)) {
|
@@ -208,45 +85,125 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
208 |
$records = array_merge($records, array(intval($chank)));
|
209 |
}
|
210 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
|
|
|
|
|
|
234 |
}
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
$
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
$
|
245 |
-
if ('' != $t_raw) $tags[$i] = implode(', ', str_getcsv($t_raw, $this->options['tags_delim']));
|
246 |
}
|
247 |
-
|
248 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
249 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
250 |
|
251 |
$cats = array();
|
252 |
|
@@ -254,44 +211,52 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
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)
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
|
|
|
|
|
|
|
|
|
|
276 |
}
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
|
|
|
|
|
|
|
|
284 |
}
|
285 |
-
}
|
286 |
-
} 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();
|
297 |
$taxonomies_param = $this->options['type'].'_taxonomies';
|
@@ -302,212 +267,295 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
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)
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
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 |
-
|
351 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
352 |
}
|
353 |
-
|
|
|
354 |
}
|
355 |
}
|
356 |
}; endif;
|
357 |
-
// [/custom taxonomies]
|
358 |
-
|
359 |
-
|
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>
|
379 |
-
$logger and call_user_func($logger, __('<b>WARNING</b>: No
|
|
|
380 |
} else {
|
381 |
-
$logger and call_user_func($logger, __('Composing URLs for
|
382 |
-
$
|
383 |
-
if ($this->options['
|
384 |
-
// Detect if
|
385 |
-
$
|
386 |
-
if (!empty($
|
387 |
$parse_multiple = true;
|
388 |
-
foreach($
|
389 |
|
390 |
if ($parse_multiple)
|
391 |
{
|
392 |
-
foreach($
|
393 |
{
|
394 |
-
$
|
395 |
-
foreach($
|
396 |
}
|
397 |
}
|
398 |
else
|
399 |
{
|
400 |
-
$
|
401 |
}
|
402 |
}
|
403 |
|
404 |
} else {
|
405 |
-
count($titles) and $
|
406 |
}
|
407 |
-
}
|
408 |
-
|
|
|
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'];
|
415 |
} else {
|
416 |
$post_type = $this->options['type'];
|
417 |
-
}
|
418 |
-
|
419 |
$current_post_ids = array();
|
420 |
-
foreach ($titles as $i => $void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
421 |
$articleData = array(
|
422 |
'post_type' => $post_type,
|
423 |
'post_status' => $this->options['status'],
|
424 |
'comment_status' => $this->options['comment_status'],
|
425 |
'ping_status' => $this->options['ping_status'],
|
426 |
-
'post_title' => $titles[$i],
|
427 |
-
'
|
|
|
|
|
428 |
'post_date' => $dates[$i],
|
429 |
'post_date_gmt' => get_gmt_from_date($dates[$i]),
|
430 |
-
'post_author' => $
|
|
|
431 |
);
|
432 |
-
|
433 |
-
|
434 |
-
'post_category' => $cats[$i],
|
435 |
-
'tags_input' => $tags[$i],
|
436 |
-
);
|
437 |
-
} else { // page
|
438 |
$articleData += array(
|
439 |
'menu_order' => $this->options['order'],
|
440 |
'post_parent' => $this->options['parent'],
|
441 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
442 |
}
|
443 |
-
|
444 |
-
//
|
445 |
-
$
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
456 |
}
|
457 |
-
|
458 |
-
|
459 |
-
$
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
$cats_new = array();
|
467 |
-
foreach ($cats_list as $c) {
|
468 |
-
$cats_new[] = $c->cat_ID;
|
469 |
-
}
|
470 |
-
$articleData['post_category'] = $cats_new;
|
471 |
}
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
|
|
|
|
|
|
|
|
476 |
} else {
|
477 |
-
$
|
478 |
-
if (
|
479 |
-
$tags_new[] = $t->name;
|
480 |
-
}
|
481 |
-
$articleData['tags_input'] = implode(', ', $tags_new);
|
482 |
-
}
|
483 |
-
|
484 |
-
foreach (array_keys($taxonomies) as $tx_name) {
|
485 |
-
$txes_list = get_the_terms($articleData['ID'], $tx_name);
|
486 |
-
if (is_wp_error($txes_list)) {
|
487 |
-
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to get current taxonomies for article #%d, updating with those read from XML file', 'pmxi_plugin'), $articleData['ID']));
|
488 |
-
} else {
|
489 |
-
$txes_new = array();
|
490 |
foreach ($txes_list as $t) {
|
491 |
$txes_new[] = $t->name;
|
492 |
}
|
493 |
-
|
494 |
-
|
495 |
}
|
496 |
}
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
505 |
}
|
506 |
}
|
507 |
-
|
508 |
-
|
509 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
510 |
}
|
|
|
511 |
// cloak urls with `WP Wizard Cloak` if corresponding option is set
|
512 |
if ( ! empty($this->options['is_cloak']) and class_exists('PMLC_Plugin')) {
|
513 |
if (preg_match_all('%<a\s[^>]*href=(?(?=")"([^"]*)"|(?(?=\')\'([^\']*)\'|([^\s>]*)))%is', $articleData['post_content'], $matches, PREG_PATTERN_ORDER)) {
|
@@ -572,7 +620,8 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
572 |
));
|
573 |
$dest->insert();
|
574 |
} else {
|
575 |
-
$logger and call_user_func($logger, sprintf(__('<b>
|
|
|
576 |
$link = NULL;
|
577 |
}
|
578 |
}
|
@@ -582,44 +631,191 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
582 |
}
|
583 |
}
|
584 |
}
|
585 |
-
}
|
586 |
-
|
587 |
-
|
|
|
|
|
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 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
601 |
|
602 |
// [custom taxonomies]
|
603 |
foreach ($taxonomies as $tx_name => $txes) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
604 |
$term_ids = wp_set_object_terms($pid, $txes[$i], $tx_name);
|
605 |
if (is_wp_error($term_ids)) {
|
606 |
-
$logger and call_user_func($logger, __('<b>
|
|
|
607 |
}
|
608 |
}
|
609 |
// [/custom taxonomies]
|
610 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
611 |
if (empty($articleData['ID'])) {
|
|
|
612 |
$logger and call_user_func($logger, sprintf(__('`%s` post created successfully', 'pmxi_plugin'), $articleData['post_title']));
|
613 |
} else {
|
|
|
614 |
$logger and call_user_func($logger, sprintf(__('`%s` post updated successfully', 'pmxi_plugin'), $articleData['post_title']));
|
615 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
616 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
617 |
wp_cache_flush();
|
618 |
-
}
|
619 |
-
if ( ! empty($this->options['is_delete_missing'])) { // delete posts which are not in current import set
|
620 |
$logger and call_user_func($logger, 'Removing previously imported posts which are no longer actual...');
|
621 |
-
$postList = new PMXI_Post_List();
|
622 |
-
|
|
|
623 |
empty($this->options['is_keep_attachments']) and wp_delete_attachments($missingPost['post_id']);
|
624 |
wp_delete_post($missingPost['post_id'], true);
|
625 |
}
|
@@ -627,57 +823,28 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
627 |
|
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 |
}
|
637 |
|
638 |
-
if ($this->options['is_delete_source']
|
639 |
$logger and call_user_func($logger, __('Deleting source XML file...', 'pmxi_plugin'));
|
640 |
if ( ! @unlink($this->path)) {
|
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 |
{
|
@@ -688,20 +855,41 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
688 |
/**
|
689 |
* Find duplicates according to settings
|
690 |
*/
|
691 |
-
public function findDuplicates($articleData)
|
692 |
-
{
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
705 |
}
|
706 |
|
707 |
/**
|
@@ -715,9 +903,31 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
715 |
if ($keepPosts) {
|
716 |
$this->wpdb->query($this->wpdb->prepare('DELETE FROM ' . $post->getTable() . ' WHERE import_id = %s', $this->id));
|
717 |
} else {
|
|
|
718 |
foreach ($post->getBy('import_id', $this->id)->convertRecords() as $p) {
|
719 |
-
empty($this->options['is_keep_attachments']) and wp_delete_attachments($p->post_id);
|
720 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
721 |
}
|
722 |
}
|
723 |
return $this;
|
@@ -746,160 +956,3 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
746 |
}
|
747 |
|
748 |
}
|
749 |
-
|
750 |
-
/**
|
751 |
-
* Cron schedule parser
|
752 |
-
*/
|
753 |
-
class _PMXI_Import_Record_Cron_Parser
|
754 |
-
{
|
755 |
-
/**
|
756 |
-
* @var array Cron parts
|
757 |
-
*/
|
758 |
-
private $_cronParts;
|
759 |
-
|
760 |
-
/**
|
761 |
-
* Constructor
|
762 |
-
*
|
763 |
-
* @param string $schedule Cron schedule string (e.g. '8 * * * *'). The
|
764 |
-
* schedule can handle ranges (10-12) and intervals
|
765 |
-
* (*\/10 [remove the backslash]). Schedule parts should map to
|
766 |
-
* minute [0-59], hour [0-23], day of month, month [1-12], day of week [1-7]
|
767 |
-
*
|
768 |
-
* @throws InvalidArgumentException if $schedule is not a valid cron schedule
|
769 |
-
*/
|
770 |
-
public function __construct($schedule)
|
771 |
-
{
|
772 |
-
$this->_cronParts = explode(' ', $schedule);
|
773 |
-
if (count($this->_cronParts) != 5) {
|
774 |
-
throw new Exception($schedule . ' is not a valid cron schedule string');
|
775 |
-
}
|
776 |
-
}
|
777 |
-
|
778 |
-
/**
|
779 |
-
* Check if a date/time unit value satisfies a crontab unit
|
780 |
-
*
|
781 |
-
* @param DateTime $nextRun Current next run date
|
782 |
-
* @param string $unit Date/time unit type (e.g. Y, m, d, H, i)
|
783 |
-
* @param string $schedule Cron schedule variable
|
784 |
-
*
|
785 |
-
* @return bool Returns TRUE if the unit satisfies the constraint
|
786 |
-
*/
|
787 |
-
public function unitSatisfiesCron(DateTime $nextRun, $unit, $schedule)
|
788 |
-
{
|
789 |
-
$unitValue = (int)$nextRun->format($unit);
|
790 |
-
|
791 |
-
if ($schedule == '*') {
|
792 |
-
return true;
|
793 |
-
} if (strpos($schedule, '-')) {
|
794 |
-
list($first, $last) = explode('-', $schedule);
|
795 |
-
return $unitValue >= $first && $unitValue <= $last;
|
796 |
-
} else if (strpos($schedule, '*/') !== false) {
|
797 |
-
list($delimiter, $interval) = explode('*/', $schedule);
|
798 |
-
return $unitValue % (int)$interval == 0;
|
799 |
-
} else {
|
800 |
-
return $unitValue == (int)$schedule;
|
801 |
-
}
|
802 |
-
}
|
803 |
-
|
804 |
-
/**
|
805 |
-
* Get the date in which the cron will run next
|
806 |
-
*
|
807 |
-
* @param string|DateTime (optional) $fromTime Set the relative start time
|
808 |
-
*
|
809 |
-
* @return DateTime
|
810 |
-
*/
|
811 |
-
public function getNextRunDate($fromTime = 'now')
|
812 |
-
{
|
813 |
-
$nextRun = ($fromTime instanceof DateTime) ? $fromTime : new DateTime($fromTime);
|
814 |
-
$nextRun->setTime($nextRun->format('H'), $nextRun->format('i'), 0);
|
815 |
-
$nextRun->modify('+1 minute'); // make sure we don't return the very date is submitted to the function
|
816 |
-
$nextRunLimit = clone $nextRun; $nextRunLimit->modify('+1 year');
|
817 |
-
|
818 |
-
while ($nextRun < $nextRunLimit) { // Set a hard limit to bail on an impossible date
|
819 |
-
|
820 |
-
// Adjust the month until it matches. Reset day to 1 and reset time.
|
821 |
-
if ( ! $this->unitSatisfiesCron($nextRun, 'm', $this->getSchedule('month'))) {
|
822 |
-
$nextRun->modify('+1 month');
|
823 |
-
$nextRun->setDate($nextRun->format('Y'), $nextRun->format('m'), 1);
|
824 |
-
$nextRun->setTime(0, 0, 0);
|
825 |
-
continue;
|
826 |
-
}
|
827 |
-
|
828 |
-
// Adjust the day of the month by incrementing the day until it matches. Reset time.
|
829 |
-
if ( ! $this->unitSatisfiesCron($nextRun, 'd', $this->getSchedule('day_of_month'))) {
|
830 |
-
$nextRun->modify('+1 day');
|
831 |
-
$nextRun->setTime(0, 0, 0);
|
832 |
-
continue;
|
833 |
-
}
|
834 |
-
|
835 |
-
// Adjust the day of week by incrementing the day until it matches. Resest time.
|
836 |
-
if ( ! $this->unitSatisfiesCron($nextRun, 'N', $this->getSchedule('day_of_week'))) {
|
837 |
-
$nextRun->modify('+1 day');
|
838 |
-
$nextRun->setTime(0, 0, 0);
|
839 |
-
continue;
|
840 |
-
}
|
841 |
-
|
842 |
-
// Adjust the hour until it matches the set hour. Set seconds and minutes to 0
|
843 |
-
if ( ! $this->unitSatisfiesCron($nextRun, 'H', $this->getSchedule('hour'))) {
|
844 |
-
$nextRun->modify('+1 hour');
|
845 |
-
$nextRun->setTime($nextRun->format('H'), 0, 0);
|
846 |
-
continue;
|
847 |
-
}
|
848 |
-
|
849 |
-
// Adjust the minutes until it matches a set minute
|
850 |
-
if ( ! $this->unitSatisfiesCron($nextRun, 'i', $this->getSchedule('minute'))) {
|
851 |
-
$nextRun->modify('+1 minute');
|
852 |
-
continue;
|
853 |
-
}
|
854 |
-
|
855 |
-
break;
|
856 |
-
}
|
857 |
-
|
858 |
-
return $nextRun;
|
859 |
-
}
|
860 |
-
|
861 |
-
/**
|
862 |
-
* Get all or part of the cron schedule string
|
863 |
-
*
|
864 |
-
* @param string $part Specify the part to retrieve or NULL to get the full
|
865 |
-
* cron schedule string. $part can be the PHP date() part of a date
|
866 |
-
* formatted string or one of the following values:
|
867 |
-
* NULL, 'minute', 'hour', 'month', 'day_of_week', 'day_of_month'
|
868 |
-
*
|
869 |
-
* @return string
|
870 |
-
*/
|
871 |
-
public function getSchedule($part = null)
|
872 |
-
{
|
873 |
-
switch ($part) {
|
874 |
-
case 'minute': case 'i':
|
875 |
-
return $this->_cronParts[0];
|
876 |
-
case 'hour': case 'H':
|
877 |
-
return $this->_cronParts[1];
|
878 |
-
case 'day_of_month': case 'd':
|
879 |
-
return $this->_cronParts[2];
|
880 |
-
case 'month': case 'm':
|
881 |
-
return $this->_cronParts[3];
|
882 |
-
case 'day_of_week': case 'N':
|
883 |
-
return $this->_cronParts[4];
|
884 |
-
default:
|
885 |
-
return implode(' ', $this->_cronParts);
|
886 |
-
}
|
887 |
-
}
|
888 |
-
|
889 |
-
/**
|
890 |
-
* Deterime if the cron is due to run based on the current time, last run
|
891 |
-
* time, and the next run time.
|
892 |
-
*
|
893 |
-
* If the relative next run time based on the last run time is not equal to
|
894 |
-
* the next suggested run time based on the current time, then the cron
|
895 |
-
* needs to run.
|
896 |
-
*
|
897 |
-
* @param string|DateTime $lastRun (optional) Date the cron was last run.
|
898 |
-
*
|
899 |
-
* @return bool Returns TRUE if the cron is due to run or FALSE if not
|
900 |
-
*/
|
901 |
-
public function isDue($lastRun = 'now')
|
902 |
-
{
|
903 |
-
return $this->getNextRunDate($lastRun) < $this->getNextRunDate();
|
904 |
-
}
|
905 |
-
}
|
6 |
* Some pre-processing logic, such as removing control characters from xml to prevent parsing errors
|
7 |
* @param string $xml
|
8 |
*/
|
9 |
+
public static function preprocessXml( & $xml) {
|
|
|
|
|
10 |
|
11 |
+
$xml = str_replace("&", "&", str_replace("&","&", $xml));
|
12 |
|
13 |
}
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
/**
|
16 |
* Validate XML to be valid for improt
|
17 |
* @param string $xml
|
22 |
if (FALSE === $xml or '' == $xml) {
|
23 |
$errors and $errors->add('form-validation', __('XML file does not exist, not accessible or empty', 'pmxi_plugin'));
|
24 |
} else {
|
25 |
+
|
26 |
+
PMXI_Import_Record::preprocessXml($xml);
|
|
|
27 |
|
28 |
libxml_use_internal_errors(true);
|
29 |
libxml_clear_errors();
|
30 |
$_x = @simplexml_load_string($xml);
|
31 |
$xml_errors = libxml_get_errors();
|
32 |
libxml_clear_errors();
|
33 |
+
if ($xml_errors) {
|
34 |
$error_msg = '<strong>' . __('Invalid XML', 'pmxi_plugin') . '</strong><ul>';
|
35 |
foreach($xml_errors as $error) {
|
36 |
$error_msg .= '<li>';
|
41 |
$error_msg .= '</li>';
|
42 |
}
|
43 |
$error_msg .= '</ul>';
|
44 |
+
$errors and $errors->add('form-validation', $error_msg);
|
45 |
} else {
|
46 |
return true;
|
47 |
}
|
56 |
public function __construct($data = array()) {
|
57 |
parent::__construct($data);
|
58 |
$this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'imports');
|
59 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
/**
|
62 |
* Perform import operation
|
65 |
* @return PMXI_Import_Record
|
66 |
* @chainable
|
67 |
*/
|
68 |
+
public function process($xml, $logger = NULL, $chunk = false, $is_cron = false) {
|
69 |
add_filter('user_has_cap', array($this, '_filter_has_cap_unfiltered_html')); kses_init(); // do not perform special filtering for imported content
|
70 |
|
71 |
+
$this->options += PMXI_Plugin::get_default_import_options(); // make sure all options are defined
|
72 |
+
// If import process NOT in large file mode the save history file
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
|
74 |
$postRecord = new PMXI_Post_Record();
|
75 |
|
76 |
$tmp_files = array();
|
77 |
// compose records to import
|
78 |
$records = array();
|
79 |
+
$chunk_records = array();
|
80 |
if ($this->options['is_import_specified']) {
|
81 |
foreach (preg_split('% *, *%', $this->options['import_specified'], -1, PREG_SPLIT_NO_EMPTY) as $chank) {
|
82 |
if (preg_match('%^(\d+)-(\d+)$%', $chank, $mtch)) {
|
85 |
$records = array_merge($records, array(intval($chank)));
|
86 |
}
|
87 |
}
|
88 |
+
|
89 |
+
$chunk_records = $records;
|
90 |
+
|
91 |
+
if ($this->large_import == 'Yes' and !empty($records)){
|
92 |
+
|
93 |
+
$_SESSION['pmxi_import']['count'] = count($records);
|
94 |
+
|
95 |
+
$records_count = $_SESSION['pmxi_import']['created_records'] + $_SESSION['pmxi_import']['updated_records'] + $_SESSION['pmxi_import']['skipped_records'] + $_SESSION['pmxi_import']['errors'];;
|
96 |
+
|
97 |
+
if (!in_array($chunk, $records) and (!$this->options['create_chunks'] or $is_cron)){
|
98 |
+
$logger and call_user_func($logger, __('<b>SKIPPED</b>: by specified records option', 'pmxi_plugin'));
|
99 |
+
$_SESSION['pmxi_import']['warnings']++;
|
100 |
+
// Time Elapsed
|
101 |
+
if ( ! $is_cron ){
|
102 |
+
$progress_msg = '<p class="import_process_bar"> Created ' . $_SESSION['pmxi_import']['created_records'] . ' / Updated ' . $_SESSION['pmxi_import']['updated_records'] . ' of '. $_SESSION['pmxi_import']['count'].' records.</p><span class="import_percent">' . ceil(($records_count/$_SESSION['pmxi_import']['count']) * 100) . '</span><span class="warnings_count">' . $_SESSION['pmxi_import']['warnings'] . '</span><span class="errors_count">' . $_SESSION['pmxi_import']['errors'] . '</span>';
|
103 |
+
$logger and call_user_func($logger, $progress_msg);
|
104 |
+
}
|
105 |
+
$_SESSION['pmxi_import']['chunk_number']++;
|
106 |
+
return;
|
107 |
+
}
|
108 |
+
else $records = array();
|
109 |
+
}
|
110 |
}
|
111 |
+
try {
|
112 |
|
113 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing titles...', 'pmxi_plugin'));
|
114 |
$titles = XmlImportParser::factory($xml, $this->xpath, $this->template['title'], $file)->parse($records); $tmp_files[] = $file;
|
115 |
+
if ($this->large_import != 'Yes') $_SESSION['pmxi_import']['count'] = count($titles);
|
116 |
+
|
117 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing excerpts...', 'pmxi_plugin'));
|
118 |
+
$post_excerpt = array();
|
119 |
+
if (!empty($this->options['post_excerpt'])){
|
120 |
+
$post_excerpt = XmlImportParser::factory($xml, $this->xpath, $this->options['post_excerpt'], $file)->parse($records); $tmp_files[] = $file;
|
121 |
+
}
|
122 |
+
else{
|
123 |
+
count($titles) and $post_excerpt = array_fill(0, count($titles), '');
|
124 |
+
}
|
125 |
+
|
126 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing authors...', 'pmxi_plugin'));
|
127 |
+
$post_author = array();
|
128 |
+
$current_user = wp_get_current_user();
|
129 |
+
|
130 |
+
if (!empty($this->options['author'])){
|
131 |
+
$post_author = XmlImportParser::factory($xml, $this->xpath, $this->options['author'], $file)->parse($records); $tmp_files[] = $file;
|
132 |
+
foreach ($post_author as $key => $author) {
|
133 |
+
$user = get_user_by('login', $author) or $user = get_user_by('slug', $author) or $user = get_user_by('email', $author) or ctype_digit($author) and $user = get_user_by('id', $author);
|
134 |
+
$post_author[$key] = (!empty($user)) ? $user->ID : $current_user->ID;
|
135 |
+
}
|
136 |
+
}
|
137 |
+
else{
|
138 |
+
count($titles) and $post_author = array_fill(0, count($titles), $current_user->ID);
|
139 |
+
}
|
140 |
+
|
141 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing slugs...', 'pmxi_plugin'));
|
142 |
+
$post_slug = array();
|
143 |
+
if (!empty($this->options['post_slug'])){
|
144 |
+
$post_slug = XmlImportParser::factory($xml, $this->xpath, $this->options['post_slug'], $file)->parse($records); $tmp_files[] = $file;
|
145 |
+
}
|
146 |
+
else{
|
147 |
+
count($titles) and $post_slug = array_fill(0, count($titles), '');
|
148 |
+
}
|
149 |
|
150 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing contents...', 'pmxi_plugin'));
|
151 |
$contents = XmlImportParser::factory(
|
152 |
(intval($this->template['is_keep_linebreaks']) ? $xml : preg_replace('%\r\n?|\n%', ' ', $xml)),
|
153 |
$this->xpath,
|
154 |
$this->template['content'],
|
155 |
$file)->parse($records
|
156 |
); $tmp_files[] = $file;
|
157 |
+
|
158 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing dates...', 'pmxi_plugin'));
|
159 |
+
if ('specific' == $this->options['date_type']) {
|
160 |
+
$dates = XmlImportParser::factory($xml, $this->xpath, $this->options['date'], $file)->parse($records); $tmp_files[] = $file;
|
161 |
+
$warned = array(); // used to prevent the same notice displaying several times
|
162 |
+
foreach ($dates as $i => $d) {
|
163 |
+
$time = strtotime($d);
|
164 |
+
if (FALSE === $time) {
|
165 |
+
in_array($d, $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'pmxi_plugin'), $warned[] = $d));
|
166 |
+
$_SESSION['pmxi_import']['warnings']++;
|
167 |
+
$time = time();
|
168 |
+
}
|
169 |
+
$dates[$i] = date('Y-m-d H:i:s', $time);
|
170 |
}
|
171 |
+
} else {
|
172 |
+
$dates_start = XmlImportParser::factory($xml, $this->xpath, $this->options['date_start'], $file)->parse($records); $tmp_files[] = $file;
|
173 |
+
$dates_end = XmlImportParser::factory($xml, $this->xpath, $this->options['date_end'], $file)->parse($records); $tmp_files[] = $file;
|
174 |
+
$warned = array(); // used to prevent the same notice displaying several times
|
175 |
+
foreach ($dates_start as $i => $d) {
|
176 |
+
$time_start = strtotime($dates_start[$i]);
|
177 |
+
if (FALSE === $time_start) {
|
178 |
+
in_array($dates_start[$i], $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'pmxi_plugin'), $warned[] = $dates_start[$i]));
|
179 |
+
$_SESSION['pmxi_import']['warnings']++;
|
180 |
+
$time_start = time();
|
|
|
181 |
}
|
182 |
+
$time_end = strtotime($dates_end[$i]);
|
183 |
+
if (FALSE === $time_end) {
|
184 |
+
in_array($dates_end[$i], $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'pmxi_plugin'), $warned[] = $dates_end[$i]));
|
185 |
+
$_SESSION['pmxi_import']['warnings']++;
|
186 |
+
$time_end = time();
|
187 |
+
}
|
188 |
+
$dates[$i] = date('Y-m-d H:i:s', mt_rand($time_start, $time_end));
|
189 |
+
}
|
190 |
+
}
|
191 |
+
|
192 |
+
$tags = array();
|
193 |
+
if ($this->options['tags']) {
|
194 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing tags...', 'pmxi_plugin'));
|
195 |
+
$tags_raw = XmlImportParser::factory($xml, $this->xpath, $this->options['tags'], $file)->parse($records); $tmp_files[] = $file;
|
196 |
+
foreach ($tags_raw as $i => $t_raw) {
|
197 |
+
$tags[$i] = '';
|
198 |
+
if ('' != $t_raw) $tags[$i] = implode(', ', str_getcsv($t_raw, $this->options['tags_delim']));
|
199 |
}
|
200 |
+
} else {
|
201 |
+
count($titles) and $tags = array_fill(0, count($titles), '');
|
202 |
+
}
|
203 |
+
|
204 |
+
require_once(ABSPATH . 'wp-admin/includes/taxonomy.php');
|
205 |
+
|
206 |
+
if ('post' == $this->options['type']) {
|
207 |
|
208 |
$cats = array();
|
209 |
|
211 |
|
212 |
if ((!empty($categories_hierarchy) and is_array($categories_hierarchy))){
|
213 |
|
214 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing categories...', 'pmxi_plugin'));
|
215 |
$categories = array();
|
216 |
|
217 |
+
foreach ($categories_hierarchy as $k => $category): if ("" == $category->xpath) continue;
|
218 |
+
$cats_raw = XmlImportParser::factory($xml, $this->xpath, str_replace('\'','"',$category->xpath), $file)->parse($records); $tmp_files[] = $file;
|
219 |
+
$warned = array(); // used to prevent the same notice displaying several times
|
220 |
+
foreach ($cats_raw as $i => $c_raw) {
|
221 |
+
if (empty($categories_hierarchy[$k]->cat_ids[$i])) $categories_hierarchy[$k]->cat_ids[$i] = array();
|
222 |
+
if (empty($cats[$i])) $cats[$i] = array();
|
223 |
+
if ('' != $c_raw) foreach (str_getcsv($c_raw, ',') as $c_cell) if ('' != $c_cell) {
|
224 |
+
foreach (str_getcsv($c_cell, $this->options['categories_delim']) as $j => $cc) if ('' != $cc) {
|
225 |
+
$cat = get_term_by('name', trim($cc), 'category') or $cat = get_term_by('slug', trim($cc), 'category') or ctype_digit($cc) and $cat = get_term_by('id', trim($cc), 'category');
|
226 |
+
if ( !empty($categories_hierarchy[$k]->parent_id) ) {
|
227 |
+
foreach ($categories_hierarchy as $key => $value){
|
228 |
+
if ($value->item_id == $categories_hierarchy[$k]->parent_id and !empty($value->cat_ids[$i])){
|
229 |
+
foreach ($value->cat_ids[$i] as $parent) {
|
230 |
+
$cats[$i][] = array(
|
231 |
+
'name' => trim($cc),
|
232 |
+
'parent' => (is_array($parent)) ? $parent['name'] : $parent, // if parent taxonomy exists then return ID else return TITLE
|
233 |
+
'assign' => $category->assign
|
234 |
+
);
|
235 |
+
}
|
236 |
+
}
|
237 |
+
}
|
238 |
}
|
239 |
+
else {
|
240 |
+
if ( !$cat ){
|
241 |
+
$cats[$i][] = array(
|
242 |
+
'name' => trim($cc),
|
243 |
+
'parent' => false,
|
244 |
+
'assign' => $category->assign
|
245 |
+
);
|
246 |
+
}
|
247 |
+
else if ( $category->assign ){
|
248 |
+
$cats[$i][] = $cat->term_id;
|
249 |
+
}
|
250 |
}
|
251 |
+
}
|
|
|
|
|
252 |
}
|
253 |
+
$categories_hierarchy[$k]->cat_ids[$i] = $cats[$i];
|
254 |
}
|
255 |
+
endforeach;
|
256 |
+
} else{
|
257 |
count($titles) and $cats = array_fill(0, count($titles), '');
|
258 |
}
|
259 |
+
}
|
260 |
// [custom taxonomies]
|
261 |
$taxonomies = array();
|
262 |
$taxonomies_param = $this->options['type'].'_taxonomies';
|
267 |
} else {
|
268 |
$taxonomies_object_type = 'post';
|
269 |
}
|
270 |
+
|
271 |
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) {
|
272 |
+
$tx = get_taxonomy($tx_name);
|
273 |
if (in_array($taxonomies_object_type, $tx->object_type)) {
|
274 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, sprintf(__('Composing terms for `%s` taxonomy...', 'pmxi_plugin'), $tx->labels->name));
|
275 |
$txes = array();
|
276 |
+
|
277 |
+
$taxonomies_hierarchy = json_decode($tx_template);
|
278 |
+
foreach ($taxonomies_hierarchy as $k => $taxonomy){ if ("" == $taxonomy->xpath) continue;
|
279 |
+
$txes_raw = XmlImportParser::factory($xml, $this->xpath, str_replace('\'','"',$taxonomy->xpath), $file)->parse($records); $tmp_files[] = $file;
|
280 |
+
$warned = array();
|
281 |
+
foreach ($txes_raw as $i => $tx_raw) {
|
282 |
+
if (empty($taxonomies_hierarchy[$k]->txn_names[$i])) $taxonomies_hierarchy[$k]->txn_names[$i] = array();
|
283 |
+
if (empty($taxonomies[$tx_name][$i])) $taxonomies[$tx_name][$i] = array();
|
284 |
+
if ('' != $tx_raw) foreach (str_getcsv($tx_raw, ',') as $tx_cell) if ('' != $tx_cell) {
|
285 |
+
foreach (str_getcsv($tx_cell, (!empty($taxonomy->delim)) ? $taxonomy->delim : ',') as $j => $cc) if ('' != $cc) {
|
286 |
+
$cat = get_term_by('name', trim($cc), $tx_name) or $cat = get_term_by('slug', trim($cc), $tx_name) or ctype_digit($cc) and $cat = get_term_by('id', $cc, $tx_name);
|
287 |
+
if (!empty($taxonomies_hierarchy[$k]->parent_id)) {
|
288 |
+
foreach ($taxonomies_hierarchy as $key => $value){
|
289 |
+
if ($value->item_id == $taxonomies_hierarchy[$k]->parent_id and !empty($value->txn_names[$i])){
|
290 |
+
foreach ($value->txn_names[$i] as $parent) {
|
291 |
+
$taxonomies[$tx_name][$i][] = array(
|
292 |
+
'name' => trim($cc),
|
293 |
+
'parent' => (is_array($parent)) ? $parent['name'] : $parent,
|
294 |
+
'assign' => $taxonomy->assign
|
295 |
+
);
|
296 |
+
}
|
297 |
+
}
|
298 |
+
}
|
299 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
300 |
}
|
301 |
+
else {
|
302 |
+
if ( ! $cat ) {
|
303 |
+
$taxonomies[$tx_name][$i][] = array(
|
304 |
+
'name' => trim($cc),
|
305 |
+
'parent' => false,
|
306 |
+
'assign' => $taxonomy->assign
|
307 |
+
);
|
308 |
+
}
|
309 |
+
elseif ($taxonomy->assign) {
|
310 |
+
$taxonomies[$tx_name][$i][] = $cc;
|
311 |
+
}
|
312 |
+
}
|
313 |
+
}
|
314 |
}
|
315 |
+
$taxonomies_hierarchy[$k]->txn_names[$i] = $taxonomies[$tx_name][$i];
|
316 |
+
}
|
317 |
}
|
318 |
}
|
319 |
}; endif;
|
320 |
+
// [/custom taxonomies]
|
321 |
+
|
322 |
+
// serialized attachments
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
323 |
if ( ! (($uploads = wp_upload_dir()) && false === $uploads['error'])) {
|
324 |
+
$logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': ' . $uploads['error']);
|
325 |
+
$logger and call_user_func($logger, __('<b>WARNING</b>: No attachments will be created', 'pmxi_plugin'));
|
326 |
+
$_SESSION['pmxi_import']['warnings']++;
|
327 |
} else {
|
328 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing URLs for attachments files...', 'pmxi_plugin'));
|
329 |
+
$attachments = array();
|
330 |
+
if ($this->options['attachments']) {
|
331 |
+
// Detect if attachments is separated by comma
|
332 |
+
$atchs = explode(',', $this->options['attachments']);
|
333 |
+
if (!empty($atchs)){
|
334 |
$parse_multiple = true;
|
335 |
+
foreach($atchs as $atch) if (!preg_match("/{.*}/", trim($atch))) $parse_multiple = false;
|
336 |
|
337 |
if ($parse_multiple)
|
338 |
{
|
339 |
+
foreach($atchs as $atch)
|
340 |
{
|
341 |
+
$posts_attachments = XmlImportParser::factory($xml, $this->xpath, trim($atch), $file)->parse($records); $tmp_files[] = $file;
|
342 |
+
foreach($posts_attachments as $i => $val) $attachments[$i][] = $val;
|
343 |
}
|
344 |
}
|
345 |
else
|
346 |
{
|
347 |
+
$attachments = XmlImportParser::factory($xml, $this->xpath, $this->options['attachments'], $file)->parse($records); $tmp_files[] = $file;
|
348 |
}
|
349 |
}
|
350 |
|
351 |
} else {
|
352 |
+
count($titles) and $attachments = array_fill(0, count($titles), '');
|
353 |
}
|
354 |
+
}
|
355 |
+
|
356 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing unique keys...', 'pmxi_plugin'));
|
357 |
$unique_keys = XmlImportParser::factory($xml, $this->xpath, $this->options['unique_key'], $file)->parse($records); $tmp_files[] = $file;
|
358 |
|
359 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Processing posts...', 'pmxi_plugin'));
|
360 |
|
361 |
if ('post' == $this->options['type'] and '' != $this->options['custom_type']) {
|
362 |
$post_type = $this->options['custom_type'];
|
363 |
} else {
|
364 |
$post_type = $this->options['type'];
|
365 |
+
}
|
366 |
+
|
367 |
$current_post_ids = array();
|
368 |
+
foreach ($titles as $i => $void) {
|
369 |
+
|
370 |
+
if (!empty($chunk_records) and $this->large_import == 'Yes' and $this->options['create_chunks'] and !$is_cron and !in_array($_SESSION['pmxi_import']['chunk_number'], $chunk_records)) {
|
371 |
+
$_SESSION['pmxi_import']['skipped_records']++;
|
372 |
+
$_SESSION['pmxi_import']['chunk_number']++;
|
373 |
+
|
374 |
+
$logger and call_user_func($logger, __('<b>SKIPPED</b>: by specified records option', 'pmxi_plugin'));
|
375 |
+
$_SESSION['pmxi_import']['warnings']++;
|
376 |
+
// Time Elapsed
|
377 |
+
if ( ! $is_cron ){
|
378 |
+
$records_count = $_SESSION['pmxi_import']['created_records'] + $_SESSION['pmxi_import']['updated_records'] + $_SESSION['pmxi_import']['skipped_records'] + $_SESSION['pmxi_import']['errors'];
|
379 |
+
$progress_msg = '<p class="import_process_bar"> Created ' . $_SESSION['pmxi_import']['created_records'] . ' / Updated ' . $_SESSION['pmxi_import']['updated_records'] . ' of '. $_SESSION['pmxi_import']['count'].' records.</p><span class="import_percent">' . ceil(($records_count/$_SESSION['pmxi_import']['count']) * 100) . '</span><span class="warnings_count">' . $_SESSION['pmxi_import']['warnings'] . '</span><span class="errors_count">' . $_SESSION['pmxi_import']['errors'] . '</span>';
|
380 |
+
$logger and call_user_func($logger, $progress_msg);
|
381 |
+
}
|
382 |
+
|
383 |
+
continue;
|
384 |
+
}
|
385 |
+
|
386 |
$articleData = array(
|
387 |
'post_type' => $post_type,
|
388 |
'post_status' => $this->options['status'],
|
389 |
'comment_status' => $this->options['comment_status'],
|
390 |
'ping_status' => $this->options['ping_status'],
|
391 |
+
'post_title' => ($this->template['is_leave_html']) ? utf8_encode(html_entity_decode($titles[$i])) : $titles[$i],
|
392 |
+
'post_excerpt' => ($this->template['is_leave_html']) ? utf8_encode(html_entity_decode($post_excerpt[$i])) : $post_excerpt[$i],
|
393 |
+
'post_slug' => $post_slug[$i],
|
394 |
+
'post_content' => ($this->template['is_leave_html']) ? utf8_encode(html_entity_decode($contents[$i])) : $contents[$i],
|
395 |
'post_date' => $dates[$i],
|
396 |
'post_date_gmt' => get_gmt_from_date($dates[$i]),
|
397 |
+
'post_author' => $post_author[$i] ,
|
398 |
+
'tags_input' => $tags[$i]
|
399 |
);
|
400 |
+
|
401 |
+
if ('post' != $articleData['post_type']){
|
|
|
|
|
|
|
|
|
402 |
$articleData += array(
|
403 |
'menu_order' => $this->options['order'],
|
404 |
'post_parent' => $this->options['parent'],
|
405 |
);
|
406 |
+
}
|
407 |
+
|
408 |
+
// Re-import Records Matching
|
409 |
+
$post_to_update = false; $post_to_update_id = false;
|
410 |
+
|
411 |
+
// if Auto Matching re-import option selected
|
412 |
+
if ("manual" != $this->options['duplicate_matching']){
|
413 |
+
$postRecord->clear();
|
414 |
+
// find corresponding article among previously imported
|
415 |
+
$postRecord->getBy(array(
|
416 |
+
'unique_key' => $unique_keys[$i],
|
417 |
+
'import_id' => $this->id,
|
418 |
+
));
|
419 |
+
if ( ! $postRecord->isEmpty() )
|
420 |
+
$post_to_update = get_post($post_to_update_id = $postRecord->post_id);
|
421 |
+
|
422 |
+
// if Manual Matching re-import option seleted
|
423 |
+
} else {
|
424 |
+
|
425 |
+
$postRecord->clear();
|
426 |
+
// find corresponding article among previously imported
|
427 |
+
$postRecord->getBy(array(
|
428 |
+
'unique_key' => $unique_keys[$i],
|
429 |
+
'import_id' => $this->id,
|
430 |
+
));
|
431 |
+
|
432 |
+
if ('custom field' == $this->options['duplicate_indicator']) {
|
433 |
+
$custom_duplicate_value = XmlImportParser::factory($xml, $this->xpath, $this->options['custom_duplicate_value'], $file)->parse($records); $tmp_files[] = $file;
|
434 |
+
$custom_duplicate_name = XmlImportParser::factory($xml, $this->xpath, $this->options['custom_duplicate_name'], $file)->parse($records); $tmp_files[] = $file;
|
435 |
+
}
|
436 |
+
else{
|
437 |
+
count($titles) and $custom_duplicate_name = $custom_duplicate_value = array_fill(0, count($titles), '');
|
438 |
+
}
|
439 |
+
|
440 |
+
// handle duplicates according to import settings
|
441 |
+
if ($duplicates = $this->findDuplicates($articleData, $custom_duplicate_name[$i], $custom_duplicate_value[$i])) {
|
442 |
+
$duplicate_id = array_shift($duplicates);
|
443 |
+
if ($duplicate_id) {
|
444 |
+
$post_to_update = get_post($post_to_update_id = $duplicate_id);
|
445 |
+
}
|
446 |
+
}
|
447 |
}
|
448 |
+
|
449 |
+
// Duplicate record is founded
|
450 |
+
if ($post_to_update){
|
451 |
+
// Do not update already existing records option selected
|
452 |
+
if ("yes" == $this->options['is_keep_former_posts']) {
|
453 |
+
$current_post_ids[] = $_SESSION['pmxi_import']['current_post_ids'][] = $post_to_update_id;
|
454 |
+
if ($is_cron){
|
455 |
+
$tmp_array = (!empty($this->current_post_ids)) ? json_decode($this->current_post_ids, true) : array();
|
456 |
+
$tmp_array[] = $post_to_update_id;
|
457 |
+
$this->set(array(
|
458 |
+
'current_post_ids' => json_encode($tmp_array)
|
459 |
+
))->save;
|
460 |
+
}
|
461 |
+
$_SESSION['pmxi_import']['skipped_records']++;
|
462 |
+
$logger and call_user_func($logger, sprintf(__('<b>SKIPPED</b>: Previously imported record found for `%s`', 'pmxi_plugin'), $articleData['post_title']));
|
463 |
+
$_SESSION['pmxi_import']['warnings']++;
|
464 |
+
if ( ! $is_cron ){
|
465 |
+
$records_count = $_SESSION['pmxi_import']['created_records'] + $_SESSION['pmxi_import']['updated_records'] + $_SESSION['pmxi_import']['skipped_records'] + $_SESSION['pmxi_import']['errors'];
|
466 |
+
$progress_msg = '<p class="import_process_bar"> Created ' . $_SESSION['pmxi_import']['created_records'] . ' / Updated ' . $_SESSION['pmxi_import']['updated_records'] . ' of '. $_SESSION['pmxi_import']['count'].' records.</p><span class="import_percent">' . ceil(($records_count/$_SESSION['pmxi_import']['count']) * 100) . '</span><span class="warnings_count">' . $_SESSION['pmxi_import']['warnings'] . '</span><span class="errors_count">' . $_SESSION['pmxi_import']['errors'] . '</span>';
|
467 |
+
$logger and call_user_func($logger, $progress_msg);
|
468 |
+
}
|
469 |
+
$_SESSION['pmxi_import']['chunk_number']++;
|
470 |
+
continue;
|
471 |
+
}
|
472 |
+
$articleData['ID'] = $post_to_update_id;
|
473 |
+
// preserve date of already existing article when duplicate is found
|
474 |
+
if ($this->options['is_keep_categories']) { // preserve categories and tags of already existing article if corresponding setting is specified
|
475 |
+
$cats_list = get_the_category($articleData['ID']);
|
476 |
+
if (is_wp_error($cats_list)) {
|
477 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to get current categories for article #%d, updating with those read from XML file', 'pmxi_plugin'), $articleData['ID']));
|
478 |
+
$_SESSION['pmxi_import']['warnings']++;
|
479 |
+
} else {
|
480 |
+
$cats_new = array();
|
481 |
+
foreach ($cats_list as $c) {
|
482 |
+
$cats_new[] = $c->cat_ID;
|
483 |
+
}
|
484 |
+
$cats[$i] = $cats_new;
|
485 |
}
|
486 |
+
|
487 |
+
$tags_list = get_the_tags($articleData['ID']);
|
488 |
+
if (is_wp_error($tags_list)) {
|
489 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to get current tags for article #%d, updating with those read from XML file', 'pmxi_plugin'), $articleData['ID']));
|
490 |
+
$_SESSION['pmxi_import']['warnings']++;
|
491 |
+
} else {
|
492 |
+
$tags_new = array();
|
493 |
+
if ($tags_list) foreach ($tags_list as $t) {
|
494 |
+
$tags_new[] = $t->name;
|
|
|
|
|
|
|
|
|
|
|
495 |
}
|
496 |
+
$articleData['tags_input'] = implode(', ', $tags_new);
|
497 |
+
}
|
498 |
+
|
499 |
+
foreach (array_keys($taxonomies) as $tx_name) {
|
500 |
+
$txes_list = get_the_terms($articleData['ID'], $tx_name);
|
501 |
+
if (is_wp_error($txes_list)) {
|
502 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to get current taxonomies for article #%d, updating with those read from XML file', 'pmxi_plugin'), $articleData['ID']));
|
503 |
+
$_SESSION['pmxi_import']['warnings']++;
|
504 |
} else {
|
505 |
+
$txes_new = array();
|
506 |
+
if (!empty($txes_list)):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
507 |
foreach ($txes_list as $t) {
|
508 |
$txes_new[] = $t->name;
|
509 |
}
|
510 |
+
endif;
|
511 |
+
$taxonomies[$tx_name][$i] = $txes_new;
|
512 |
}
|
513 |
}
|
514 |
+
}
|
515 |
+
if ($this->options['is_keep_dates']) { // preserve date of already existing article when duplicate is found
|
516 |
+
$articleData['post_date'] = $post_to_update->post_date;
|
517 |
+
$articleData['post_date_gmt'] = $post_to_update->post_date_gmt;
|
518 |
+
}
|
519 |
+
if ($this->options['is_keep_status']) { // preserve status and trashed flag
|
520 |
+
$articleData['post_status'] = $post_to_update->post_status;
|
521 |
+
}
|
522 |
+
if ($this->options['is_keep_content']){
|
523 |
+
$articleData['post_content'] = $post_to_update->post_content;
|
524 |
+
}
|
525 |
+
if ($this->options['is_keep_title']){
|
526 |
+
$articleData['post_title'] = $post_to_update->post_title;
|
527 |
+
}
|
528 |
+
if ($this->options['is_keep_excerpt']){
|
529 |
+
$articleData['post_excerpt'] = $post_to_update->post_excerpt;
|
530 |
+
}
|
531 |
+
if ($this->options['is_keep_menu_order']){
|
532 |
+
$articleData['menu_order'] = $post_to_update->menu_order;
|
533 |
+
}
|
534 |
+
// handle obsolete attachments (i.e. delete or keep) according to import settings
|
535 |
+
if ( ! $this->options['is_keep_images'] and ! $this->options['no_create_featured_image']){
|
536 |
+
wp_delete_attachments($articleData['ID']);
|
537 |
}
|
538 |
}
|
539 |
+
elseif ( ! $postRecord->isEmpty() ){
|
540 |
+
|
541 |
+
// existing post not found though it's track was found... clear the leftover, plugin will continue to treat record as new
|
542 |
+
$postRecord->delete();
|
543 |
+
|
544 |
+
}
|
545 |
+
|
546 |
+
// no new records are created. it will only update posts it finds matching duplicates for
|
547 |
+
if ($this->options['not_create_records'] and empty($articleData['ID'])){
|
548 |
+
$_SESSION['pmxi_import']['skipped_records']++;
|
549 |
+
$logger and call_user_func($logger, sprintf(__('<b>SKIPPED</b>: by "Not add new records" option for `%s`', 'pmxi_plugin'), $articleData['post_title']));
|
550 |
+
if ( ! $is_cron ){
|
551 |
+
$records_count = $_SESSION['pmxi_import']['created_records'] + $_SESSION['pmxi_import']['updated_records'] + $_SESSION['pmxi_import']['skipped_records'] + $_SESSION['pmxi_import']['errors'];
|
552 |
+
$progress_msg = '<p class="import_process_bar"> Created ' . $_SESSION['pmxi_import']['created_records'] . ' / Updated ' . $_SESSION['pmxi_import']['updated_records'] . ' of '. $_SESSION['pmxi_import']['count'].' records.</p><span class="import_percent">' . ceil(($records_count/$_SESSION['pmxi_import']['count']) * 100) . '</span><span class="warnings_count">' . $_SESSION['pmxi_import']['warnings'] . '</span><span class="errors_count">' . $_SESSION['pmxi_import']['errors'] . '</span>';
|
553 |
+
$logger and call_user_func($logger, $progress_msg);
|
554 |
+
}
|
555 |
+
$_SESSION['pmxi_import']['chunk_number']++;
|
556 |
+
continue;
|
557 |
}
|
558 |
+
|
559 |
// cloak urls with `WP Wizard Cloak` if corresponding option is set
|
560 |
if ( ! empty($this->options['is_cloak']) and class_exists('PMLC_Plugin')) {
|
561 |
if (preg_match_all('%<a\s[^>]*href=(?(?=")"([^"]*)"|(?(?=\')\'([^\']*)\'|([^\s>]*)))%is', $articleData['post_content'], $matches, PREG_PATTERN_ORDER)) {
|
620 |
));
|
621 |
$dest->insert();
|
622 |
} else {
|
623 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to create cloaked link for %s', 'pmxi_plugin'), $url));
|
624 |
+
$_SESSION['pmxi_import']['warnings']++;
|
625 |
$link = NULL;
|
626 |
}
|
627 |
}
|
631 |
}
|
632 |
}
|
633 |
}
|
634 |
+
}
|
635 |
+
|
636 |
+
// insert article being imported
|
637 |
+
$pid = wp_insert_post($articleData, true);
|
638 |
+
|
639 |
if (is_wp_error($pid)) {
|
640 |
+
$logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': ' . $pid->get_error_message());
|
641 |
+
$_SESSION['pmxi_import']['errors']++;
|
642 |
} else {
|
643 |
|
644 |
do_action( 'pmxi_saved_post', $pid); // hook that was triggered immediately after post saved
|
645 |
|
646 |
+
$current_post_ids[] = $_SESSION['pmxi_import']['current_post_ids'][] = $pid;
|
647 |
+
if ($is_cron){
|
648 |
+
$tmp_array = (!empty($this->current_post_ids)) ? json_decode($this->current_post_ids, true) : array();
|
649 |
+
$tmp_array[] = $pid;
|
650 |
+
$this->set(array(
|
651 |
+
'current_post_ids' => json_encode($tmp_array)
|
652 |
+
))->save();
|
653 |
+
}
|
654 |
+
if ("manual" != $this->options['duplicate_matching'] or empty($articleData['ID'])){
|
655 |
+
// associate post with import
|
656 |
+
$postRecord->isEmpty() and $postRecord->set(array(
|
657 |
+
'post_id' => $pid,
|
658 |
+
'import_id' => $this->id,
|
659 |
+
'unique_key' => $unique_keys[$i],
|
660 |
+
))->insert();
|
661 |
+
}
|
662 |
+
|
663 |
+
if ('post' != $articleData['post_type'] and !empty($this->options['page_template'])) update_post_meta($pid, '_wp_page_template', $this->options['page_template']);
|
664 |
+
|
665 |
+
// [attachments]
|
666 |
+
if ( ! empty($uploads) and false === $uploads['error'] and !empty($attachments[$i])) {
|
667 |
+
|
668 |
+
// you must first include the image.php file
|
669 |
+
// for the function wp_generate_attachment_metadata() to work
|
670 |
+
require_once(ABSPATH . 'wp-admin/includes/image.php');
|
671 |
+
|
672 |
+
if ( ! is_array($attachments[$i]) ) $attachments[$i] = array($attachments[$i]);
|
673 |
+
|
674 |
+
foreach ($attachments[$i] as $attachment) { if ("" == $attachment) continue;
|
675 |
+
|
676 |
+
$atchs = str_getcsv($attachment, $this->options['atch_delim']);
|
677 |
+
|
678 |
+
if (!empty($atchs)) {
|
679 |
+
foreach ($atchs as $atch_url) { if (empty($atch_url)) continue;
|
680 |
+
|
681 |
+
$attachment_filename = wp_unique_filename($uploads['path'], basename(parse_url(trim($atch_url), PHP_URL_PATH)));
|
682 |
+
$attachment_filepath = $uploads['path'] . '/' . url_title($attachment_filename);
|
683 |
+
|
684 |
+
if ( ! file_put_contents($attachment_filepath, @file_get_contents(trim($atch_url))) and ! get_file_curl(trim($atch_url), $attachment_filepath)) {
|
685 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Attachment file %s cannot be saved locally as %s', 'pmxi_plugin'), trim($atch_url), $attachment_filepath));
|
686 |
+
$_SESSION['pmxi_import']['warnings']++;
|
687 |
+
unlink($attachment_filepath); // delete file since failed upload may result in empty file created
|
688 |
+
} elseif( ! $wp_filetype = wp_check_filetype(basename($attachment_filename), null )) {
|
689 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Can\'t detect attachment file type %s', 'pmxi_plugin'), trim($atch_url)));
|
690 |
+
$_SESSION['pmxi_import']['warnings']++;
|
691 |
+
} else {
|
692 |
+
|
693 |
+
$attachment_data = array(
|
694 |
+
'guid' => $uploads['baseurl'] . _wp_relative_upload_path( $attachment_filepath ),
|
695 |
+
'post_mime_type' => $wp_filetype['type'],
|
696 |
+
'post_title' => preg_replace('/\.[^.]+$/', '', basename($attachment_filepath)),
|
697 |
+
'post_content' => '',
|
698 |
+
'post_status' => 'inherit'
|
699 |
+
);
|
700 |
+
$attach_id = wp_insert_attachment( $attachment_data, $attachment_filepath, $pid );
|
701 |
+
|
702 |
+
if (is_wp_error($attach_id)) {
|
703 |
+
$logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': ' . $pid->get_error_message());
|
704 |
+
$_SESSION['pmxi_import']['warnings']++;
|
705 |
+
} else {
|
706 |
+
wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $attachment_filepath));
|
707 |
+
}
|
708 |
+
}
|
709 |
+
}
|
710 |
+
}
|
711 |
+
}
|
712 |
+
}
|
713 |
+
// [/attachments]
|
714 |
|
715 |
// [custom taxonomies]
|
716 |
foreach ($taxonomies as $tx_name => $txes) {
|
717 |
+
// create term if not exists
|
718 |
+
foreach ($txes[$i] as $key => $single_tax) {
|
719 |
+
if (is_array($single_tax)){
|
720 |
+
$term = term_exists( $single_tax['name'], $tx_name, (!empty($single_tax['parent'])) ? $single_tax['parent'] : '' );
|
721 |
+
if ( empty($term) ){
|
722 |
+
$term_attr = (!empty($single_tax['parent'])) ? $term_attr = array('parent'=> $single_tax['parent']) : '';
|
723 |
+
|
724 |
+
$term = wp_insert_term(
|
725 |
+
$single_tax['name'], // the term
|
726 |
+
$tx_name, // the taxonomy
|
727 |
+
$term_attr
|
728 |
+
);
|
729 |
+
}
|
730 |
+
|
731 |
+
if ( empty($term) or is_wp_error($term) ){
|
732 |
+
unset($txes[$i][$key]);
|
733 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: `%s`', 'pmxi_plugin'), $term->get_error_message()));
|
734 |
+
$_SESSION['pmxi_import']['warnings']++;
|
735 |
+
}
|
736 |
+
else{
|
737 |
+
$cat_id = $term['term_id'];
|
738 |
+
if ($cat_id and $single_tax['assign'])
|
739 |
+
$txes[$i][$key] = $single_tax['name'];
|
740 |
+
else
|
741 |
+
unset($txes[$i][$key]);
|
742 |
+
}
|
743 |
+
}
|
744 |
+
}
|
745 |
+
|
746 |
+
// associate taxes with post
|
747 |
$term_ids = wp_set_object_terms($pid, $txes[$i], $tx_name);
|
748 |
if (is_wp_error($term_ids)) {
|
749 |
+
$logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': '.$term_ids->get_error_message());
|
750 |
+
$_SESSION['pmxi_import']['warnings']++;
|
751 |
}
|
752 |
}
|
753 |
// [/custom taxonomies]
|
754 |
|
755 |
+
// [categories]
|
756 |
+
if (!empty($cats[$i])){
|
757 |
+
// create categories if it's doesn't exists
|
758 |
+
foreach ($cats[$i] as $key => $single_cat) {
|
759 |
+
if (is_array($single_cat)){
|
760 |
+
if (!empty($single_cat['parent'])){
|
761 |
+
$cat = get_term_by('name', $single_cat['parent'], 'category') or $cat = get_term_by('slug', $single_cat['parent'], 'category') or ctype_digit($single_cat['parent']) and $cat = get_term_by('id', $single_cat['parent'], 'category');
|
762 |
+
if ($cat)
|
763 |
+
$cat_id = wp_create_category($single_cat['name'], $cat->term_id);
|
764 |
+
}
|
765 |
+
else $cat_id = wp_create_category($single_cat['name']);
|
766 |
+
|
767 |
+
if ($cat_id and $single_cat['assign'])
|
768 |
+
$cats[$i][$key] = $cat_id;
|
769 |
+
}
|
770 |
+
}
|
771 |
+
// associate categories with post
|
772 |
+
$cats_ids = wp_set_post_terms($pid, $cats[$i], 'category');
|
773 |
+
if (is_wp_error($cats_ids)) {
|
774 |
+
$logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': '.$cats_ids->get_error_message());
|
775 |
+
$_SESSION['pmxi_import']['warnings']++;
|
776 |
+
}
|
777 |
+
}
|
778 |
+
// [/categories]
|
779 |
+
|
780 |
if (empty($articleData['ID'])) {
|
781 |
+
$_SESSION['pmxi_import']['created_records']++;
|
782 |
$logger and call_user_func($logger, sprintf(__('`%s` post created successfully', 'pmxi_plugin'), $articleData['post_title']));
|
783 |
} else {
|
784 |
+
$_SESSION['pmxi_import']['updated_records']++;
|
785 |
$logger and call_user_func($logger, sprintf(__('`%s` post updated successfully', 'pmxi_plugin'), $articleData['post_title']));
|
786 |
}
|
787 |
+
|
788 |
+
$records_count = 0;
|
789 |
+
|
790 |
+
// Time Elapsed
|
791 |
+
if ( ! $is_cron){
|
792 |
+
|
793 |
+
if ($this->large_import == 'No') $_SESSION['pmxi_import']['count'] = count($titles);
|
794 |
+
|
795 |
+
$records_count = $_SESSION['pmxi_import']['created_records'] + $_SESSION['pmxi_import']['updated_records'] + $_SESSION['pmxi_import']['skipped_records'] + $_SESSION['pmxi_import']['errors'];
|
796 |
+
|
797 |
+
$progress_msg = '<p class="import_process_bar"> Created ' . $_SESSION['pmxi_import']['created_records'] . ' / Updated ' . $_SESSION['pmxi_import']['updated_records'] . ' of '. $_SESSION['pmxi_import']['count'].' records.</p><span class="import_percent">' . ceil(($records_count/$_SESSION['pmxi_import']['count']) * 100) . '</span><span class="warnings_count">' . $_SESSION['pmxi_import']['warnings'] . '</span><span class="errors_count">' . $_SESSION['pmxi_import']['errors'] . '</span>';
|
798 |
+
$logger and call_user_func($logger, $progress_msg);
|
799 |
+
}
|
800 |
+
|
801 |
}
|
802 |
+
|
803 |
+
if ($this->large_import == 'Yes' and $chunk){
|
804 |
+
$this->set(array(
|
805 |
+
'imported' => $this->imported + 1,
|
806 |
+
'created' => $_SESSION['pmxi_import']['created_records'],
|
807 |
+
'updated' => $_SESSION['pmxi_import']['updated_records']
|
808 |
+
))->save();
|
809 |
+
$_SESSION['pmxi_import']['chunk_number']++;
|
810 |
+
}
|
811 |
+
|
812 |
wp_cache_flush();
|
813 |
+
}
|
814 |
+
if (!$is_cron and ($records_count == $_SESSION['pmxi_import']['count'] + $_SESSION['pmxi_import']['skipped_records']) and ! empty($this->options['is_delete_missing'])) { // delete posts which are not in current import set
|
815 |
$logger and call_user_func($logger, 'Removing previously imported posts which are no longer actual...');
|
816 |
+
$postList = new PMXI_Post_List();
|
817 |
+
|
818 |
+
foreach ($postList->getBy(array('import_id' => $this->id, 'post_id NOT IN' => $_SESSION['pmxi_import']['current_post_ids'])) as $missingPost) {
|
819 |
empty($this->options['is_keep_attachments']) and wp_delete_attachments($missingPost['post_id']);
|
820 |
wp_delete_post($missingPost['post_id'], true);
|
821 |
}
|
823 |
|
824 |
} catch (XmlImportException $e) {
|
825 |
$logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': ' . $e->getMessage());
|
826 |
+
$_SESSION['pmxi_import']['errors']++;
|
827 |
+
}
|
828 |
+
|
829 |
$this->set('registered_on', date('Y-m-d H:i:s'))->save(); // specify execution is successful
|
830 |
|
831 |
+
!$is_cron and ($records_count == $_SESSION['pmxi_import']['count'] + $_SESSION['pmxi_import']['skipped_records']) and $logger and call_user_func($logger, __('Cleaning temporary data...', 'pmxi_plugin'));
|
832 |
foreach ($tmp_files as $file) { // remove all temporary files created
|
833 |
unlink($file);
|
834 |
}
|
835 |
|
836 |
+
if (($is_cron or $records_count == $_SESSION['pmxi_import']['count'] + $_SESSION['pmxi_import']['skipped_records']) and $this->options['is_delete_source']) {
|
837 |
$logger and call_user_func($logger, __('Deleting source XML file...', 'pmxi_plugin'));
|
838 |
if ( ! @unlink($this->path)) {
|
839 |
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to remove %s', 'pmxi_plugin'), $this->path));
|
840 |
}
|
841 |
}
|
842 |
+
!$is_cron and ($records_count == $_SESSION['pmxi_import']['count'] + $_SESSION['pmxi_import']['skipped_records']) and $logger and call_user_func($logger, 'Done');
|
843 |
|
844 |
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
|
845 |
|
846 |
return $this;
|
847 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
848 |
|
849 |
public function _filter_has_cap_unfiltered_html($caps)
|
850 |
{
|
855 |
/**
|
856 |
* Find duplicates according to settings
|
857 |
*/
|
858 |
+
public function findDuplicates($articleData, $custom_duplicate_name = '', $custom_duplicate_value = '')
|
859 |
+
{
|
860 |
+
if ('custom field' == $this->options['duplicate_indicator']){
|
861 |
+
$duplicate_ids = array();
|
862 |
+
$args = array(
|
863 |
+
'post_type' => $articleData['post_type'],
|
864 |
+
'meta_query' => array(
|
865 |
+
array(
|
866 |
+
'key' => $custom_duplicate_name,
|
867 |
+
'value' => $custom_duplicate_value,
|
868 |
+
)
|
869 |
+
)
|
870 |
+
);
|
871 |
+
$query = new WP_Query( $args );
|
872 |
+
|
873 |
+
if ( $query->have_posts() ) $duplicate_ids[] = $query->post->ID;
|
874 |
+
|
875 |
+
wp_reset_postdata();
|
876 |
+
|
877 |
+
return $duplicate_ids;
|
878 |
+
}
|
879 |
+
else{
|
880 |
+
$field = 'post_' . $this->options['duplicate_indicator']; // post_title or post_content
|
881 |
+
return $this->wpdb->get_col($this->wpdb->prepare("
|
882 |
+
SELECT ID FROM " . $this->wpdb->posts . "
|
883 |
+
WHERE
|
884 |
+
post_type = %s
|
885 |
+
AND ID != %s
|
886 |
+
AND REPLACE(REPLACE(REPLACE($field, ' ', ''), '\\t', ''), '\\n', '') = %s
|
887 |
+
",
|
888 |
+
$articleData['post_type'],
|
889 |
+
isset($articleData['ID']) ? $articleData['ID'] : 0,
|
890 |
+
preg_replace('%[ \\t\\n]%', '', $articleData[$field])
|
891 |
+
));
|
892 |
+
}
|
893 |
}
|
894 |
|
895 |
/**
|
903 |
if ($keepPosts) {
|
904 |
$this->wpdb->query($this->wpdb->prepare('DELETE FROM ' . $post->getTable() . ' WHERE import_id = %s', $this->id));
|
905 |
} else {
|
906 |
+
$ids = array();
|
907 |
foreach ($post->getBy('import_id', $this->id)->convertRecords() as $p) {
|
908 |
+
empty($this->options['is_keep_attachments']) and empty($this->options['is_keep_images']) and wp_delete_attachments($p->post_id);
|
909 |
+
$ids[] = $p->post_id;
|
910 |
+
//wp_delete_post($p->post_id, TRUE);
|
911 |
+
}
|
912 |
+
if (!empty($ids)){
|
913 |
+
|
914 |
+
/*$sql = "delete a,b,c,d
|
915 |
+
FROM ".$this->wpdb->posts." a
|
916 |
+
LEFT JOIN ".$this->wpdb->term_relationships." b ON ( a.ID = b.object_id )
|
917 |
+
LEFT JOIN ".$this->wpdb->postmeta." c ON ( a.ID = c.post_id )
|
918 |
+
LEFT JOIN ".$this->wpdb->term_taxonomy." d ON ( d.term_taxonomy_id = b.term_taxonomy_id )
|
919 |
+
LEFT JOIN ".$this->wpdb->terms." e ON ( e.term_id = d.term_id )
|
920 |
+
WHERE a.ID IN (".implode(',', $ids).");";*/
|
921 |
+
|
922 |
+
$sql = "delete a,b,c
|
923 |
+
FROM ".$this->wpdb->posts." a
|
924 |
+
LEFT JOIN ".$this->wpdb->term_relationships." b ON ( a.ID = b.object_id )
|
925 |
+
LEFT JOIN ".$this->wpdb->postmeta." c ON ( a.ID = c.post_id )
|
926 |
+
WHERE a.ID IN (".implode(',', $ids).");";
|
927 |
+
|
928 |
+
$this->wpdb->query(
|
929 |
+
$this->wpdb->prepare($sql)
|
930 |
+
);
|
931 |
}
|
932 |
}
|
933 |
return $this;
|
956 |
}
|
957 |
|
958 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
plugin.php
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
<?php
|
2 |
/*
|
3 |
-
Plugin Name: WP All Import
|
4 |
-
Plugin URI: http://www.wpallimport.com/
|
5 |
-
Description:
|
6 |
-
Version:
|
7 |
Author: Soflyy
|
8 |
*/
|
9 |
/**
|
@@ -63,8 +63,11 @@ final class PMXI_Plugin {
|
|
63 |
* @var string
|
64 |
*/
|
65 |
const FILE = __FILE__;
|
66 |
-
|
67 |
-
|
|
|
|
|
|
|
68 |
|
69 |
/**
|
70 |
* Return singletone instance
|
@@ -134,12 +137,24 @@ final class PMXI_Plugin {
|
|
134 |
return ($this->isNetwork() ? $wpdb->base_prefix : $wpdb->prefix) . self::PREFIX;
|
135 |
}
|
136 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
/**
|
138 |
* Class constructor containing dispatching logic
|
139 |
* @param string $rootDir Plugin root dir
|
140 |
* @param string $pluginFilePath Plugin main file
|
141 |
*/
|
142 |
protected function __construct() {
|
|
|
|
|
|
|
143 |
// regirster autoloading method
|
144 |
if (function_exists('__autoload') and ! in_array('__autoload', spl_autoload_functions())) { // make sure old way of autoloading classes is not broken
|
145 |
spl_autoload_register('__autoload');
|
@@ -151,11 +166,19 @@ final class PMXI_Plugin {
|
|
151 |
require_once $filePath;
|
152 |
}
|
153 |
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
// init plugin options
|
155 |
$option_name = get_class($this) . '_Options';
|
156 |
$options_default = PMXI_Config::createFromFile(self::ROOT_DIR . '/config/options.php')->toArray();
|
157 |
$this->options = array_intersect_key(get_option($option_name, array()), $options_default) + $options_default;
|
158 |
$this->options = array_intersect_key($options_default, array_flip(array('info_api_url'))) + $this->options; // make sure hidden options apply upon plugin reactivation
|
|
|
|
|
159 |
update_option($option_name, $this->options);
|
160 |
$this->options = get_option(get_class($this) . '_Options');
|
161 |
|
@@ -196,6 +219,8 @@ final class PMXI_Plugin {
|
|
196 |
// register admin page pre-dispatcher
|
197 |
add_action('admin_init', array($this, '__adminInit'));
|
198 |
|
|
|
|
|
199 |
}
|
200 |
|
201 |
/**
|
@@ -385,12 +410,18 @@ final class PMXI_Plugin {
|
|
385 |
}
|
386 |
|
387 |
/**
|
388 |
-
* Method perfoms transition from version when file
|
389 |
* NOTE: the function can be removed when plugin version progress and it's sure matter nobody has ver 1.03
|
390 |
*/
|
391 |
public function __ver_1_04_transition_fix() {
|
392 |
-
|
393 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
394 |
}
|
395 |
|
396 |
$table = $table = $this->getTablePrefix() . 'files';
|
@@ -402,7 +433,7 @@ final class PMXI_Plugin {
|
|
402 |
$list = new PMXI_File_List();
|
403 |
for ($i = 1; $list->getBy(NULL, 'id', $i, 1)->count(); $i++) {
|
404 |
foreach ($list->convertRecords() as $file) {
|
405 |
-
$file->save(); // resave file for file to be stored in
|
406 |
}
|
407 |
}
|
408 |
|
@@ -412,6 +443,67 @@ final class PMXI_Plugin {
|
|
412 |
}
|
413 |
}
|
414 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
415 |
/**
|
416 |
* Method returns default import options, main utility of the method is to avoid warnings when new
|
417 |
* option is introduced but already registered imports don't have it
|
@@ -423,6 +515,9 @@ final class PMXI_Plugin {
|
|
423 |
'categories' => '',
|
424 |
'tags' => '',
|
425 |
'tags_delim' => ',',
|
|
|
|
|
|
|
426 |
'post_taxonomies' => array(),
|
427 |
'parent' => '',
|
428 |
'order' => '0',
|
@@ -437,27 +532,47 @@ final class PMXI_Plugin {
|
|
437 |
'custom_value' => array(),
|
438 |
'comment_status' => 'open',
|
439 |
'ping_status' => 'open',
|
440 |
-
'
|
|
|
441 |
'featured_image' => '',
|
|
|
442 |
'is_import_specified' => 0,
|
443 |
'import_specified' => '',
|
444 |
'is_delete_source' => 0,
|
445 |
'is_cloak' => 0,
|
446 |
'unique_key' => '',
|
|
|
447 |
|
448 |
'is_delete_missing' => 0,
|
449 |
-
'is_keep_former_posts' =>
|
450 |
'is_keep_status' => 0,
|
|
|
|
|
|
|
451 |
'is_keep_categories' => 0,
|
452 |
'is_keep_attachments' => 0,
|
|
|
453 |
'is_duplicates' => 0,
|
|
|
|
|
|
|
|
|
|
|
454 |
|
455 |
'duplicate_indicator' => 'title',
|
456 |
'duplicate_action' => 'keep',
|
457 |
-
'is_first_chank' => 0,
|
458 |
'is_update_previous' => 0,
|
459 |
'is_scheduled' => '',
|
460 |
-
'scheduled_period' => ''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
461 |
);
|
462 |
}
|
463 |
|
@@ -470,17 +585,18 @@ final class PMXI_Plugin {
|
|
470 |
|
471 |
$csv = new PMXI_CsvParser($csv_url);
|
472 |
|
473 |
-
|
|
|
|
|
|
|
|
|
474 |
|
475 |
}
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
*
|
480 |
-
*/
|
481 |
-
public static function detect_csv($type){
|
482 |
-
return in_array($type, self::$csv_mimes);
|
483 |
}
|
|
|
484 |
}
|
485 |
|
486 |
PMXI_Plugin::getInstance();
|
1 |
<?php
|
2 |
/*
|
3 |
+
Plugin Name: WP All Import Lite
|
4 |
+
Plugin URI: http://www.wpallimport.com/
|
5 |
+
Description: The most powerful solution for importing XML and CSV files to WordPress. Create Posts and Pages with content from any XML or CSV file. Perform scheduled updates and overwrite of existing import jobs. Free lite edition.
|
6 |
+
Version: 3.0
|
7 |
Author: Soflyy
|
8 |
*/
|
9 |
/**
|
63 |
* @var string
|
64 |
*/
|
65 |
const FILE = __FILE__;
|
66 |
+
/**
|
67 |
+
* Max allowed file size (bytes) to import in default mode
|
68 |
+
* @var int
|
69 |
+
*/
|
70 |
+
const LARGE_SIZE = 0; // all files will importing in large import mode
|
71 |
|
72 |
/**
|
73 |
* Return singletone instance
|
137 |
return ($this->isNetwork() ? $wpdb->base_prefix : $wpdb->prefix) . self::PREFIX;
|
138 |
}
|
139 |
|
140 |
+
/**
|
141 |
+
* Return prefix for wordpress database tables
|
142 |
+
* @return string
|
143 |
+
*/
|
144 |
+
public function getWPPrefix() {
|
145 |
+
global $wpdb;
|
146 |
+
return ($this->isNetwork() ? $wpdb->base_prefix : $wpdb->prefix);
|
147 |
+
}
|
148 |
+
|
149 |
/**
|
150 |
* Class constructor containing dispatching logic
|
151 |
* @param string $rootDir Plugin root dir
|
152 |
* @param string $pluginFilePath Plugin main file
|
153 |
*/
|
154 |
protected function __construct() {
|
155 |
+
|
156 |
+
// create/update required database tables
|
157 |
+
|
158 |
// regirster autoloading method
|
159 |
if (function_exists('__autoload') and ! in_array('__autoload', spl_autoload_functions())) { // make sure old way of autoloading classes is not broken
|
160 |
spl_autoload_register('__autoload');
|
166 |
require_once $filePath;
|
167 |
}
|
168 |
|
169 |
+
// create history folder
|
170 |
+
$uploads = wp_upload_dir();
|
171 |
+
if (!is_dir($uploads['basedir'] . '/wpallimport_history')) wp_mkdir_p($uploads['basedir'] . '/wpallimport_history');
|
172 |
+
// create logs folder
|
173 |
+
if (!is_dir($uploads['basedir'] . '/wpallimport_logs')) wp_mkdir_p($uploads['basedir'] . '/wpallimport_logs');
|
174 |
+
|
175 |
// init plugin options
|
176 |
$option_name = get_class($this) . '_Options';
|
177 |
$options_default = PMXI_Config::createFromFile(self::ROOT_DIR . '/config/options.php')->toArray();
|
178 |
$this->options = array_intersect_key(get_option($option_name, array()), $options_default) + $options_default;
|
179 |
$this->options = array_intersect_key($options_default, array_flip(array('info_api_url'))) + $this->options; // make sure hidden options apply upon plugin reactivation
|
180 |
+
if ('' == $this->options['cron_job_key']) $this->options['cron_job_key'] = url_title(rand_char(12));
|
181 |
+
|
182 |
update_option($option_name, $this->options);
|
183 |
$this->options = get_option(get_class($this) . '_Options');
|
184 |
|
219 |
// register admin page pre-dispatcher
|
220 |
add_action('admin_init', array($this, '__adminInit'));
|
221 |
|
222 |
+
$this->__add_feed_type_fix(); // feature to version 2.22
|
223 |
+
|
224 |
}
|
225 |
|
226 |
/**
|
410 |
}
|
411 |
|
412 |
/**
|
413 |
+
* Method perfoms transition from version when file uploads has been stored in dabase to the solution when it stored on disk
|
414 |
* NOTE: the function can be removed when plugin version progress and it's sure matter nobody has ver 1.03
|
415 |
*/
|
416 |
public function __ver_1_04_transition_fix() {
|
417 |
+
$uploads = wp_upload_dir();
|
418 |
+
|
419 |
+
if ( ! is_dir($uploads['basedir'] . '/wpallimport_history') or ! is_writable($uploads['basedir'] . '/wpallimport_history')) {
|
420 |
+
die(sprintf(__('Uploads folder %s must be writable', 'pmxi_plugin'), $uploads['basedir'] . '/wpallimport_history'));
|
421 |
+
}
|
422 |
+
|
423 |
+
if ( ! is_dir($uploads['basedir'] . '/wpallimport_logs') or ! is_writable($uploads['basedir'] . '/wpallimport_logs')) {
|
424 |
+
die(sprintf(__('Uploads folder %s must be writable', 'pmxi_plugin'), $uploads['basedir'] . '/wpallimport_logs'));
|
425 |
}
|
426 |
|
427 |
$table = $table = $this->getTablePrefix() . 'files';
|
433 |
$list = new PMXI_File_List();
|
434 |
for ($i = 1; $list->getBy(NULL, 'id', $i, 1)->count(); $i++) {
|
435 |
foreach ($list->convertRecords() as $file) {
|
436 |
+
$file->save(); // resave file for file to be stored in uploads folder
|
437 |
}
|
438 |
}
|
439 |
|
443 |
}
|
444 |
}
|
445 |
|
446 |
+
public function __add_feed_type_fix(){
|
447 |
+
|
448 |
+
$table = $this->getTablePrefix() . 'imports';
|
449 |
+
global $wpdb;
|
450 |
+
$tablefields = $wpdb->get_results("DESCRIBE {$table};");
|
451 |
+
$large_import = false;
|
452 |
+
$root_element = false;
|
453 |
+
$processing = false;
|
454 |
+
$triggered = false;
|
455 |
+
$queue_chunk_number = false;
|
456 |
+
$current_post_ids = false;
|
457 |
+
$first_import = false;
|
458 |
+
$count = false;
|
459 |
+
$friendly_name = false;
|
460 |
+
$imported = false;
|
461 |
+
$created = false;
|
462 |
+
$updated = false;
|
463 |
+
$skipped = false;
|
464 |
+
|
465 |
+
// Check if field exists
|
466 |
+
foreach ($tablefields as $tablefield) {
|
467 |
+
if ('large_import' == $tablefield->Field) $large_import = true;
|
468 |
+
if ('root_element' == $tablefield->Field) $root_element = true;
|
469 |
+
if ('processing' == $tablefield->Field) $processing = true;
|
470 |
+
if ('triggered' == $tablefield->Field) $triggered = true;
|
471 |
+
if ('current_post_ids' == $tablefield->Field) $current_post_ids = true;
|
472 |
+
if ('queue_chunk_number' == $tablefield->Field) $queue_chunk_number = true;
|
473 |
+
if ('first_import' == $tablefield->Field) $first_import = true;
|
474 |
+
if ('count' == $tablefield->Field) $count = true;
|
475 |
+
if ('friendly_name' == $tablefield->Field) $friendly_name = true;
|
476 |
+
if ('imported' == $tablefield->Field) $imported = true;
|
477 |
+
if ('created' == $tablefield->Field) $created = true;
|
478 |
+
if ('updated' == $tablefield->Field) $updated = true;
|
479 |
+
if ('skipped' == $tablefield->Field) $skipped = true;
|
480 |
+
}
|
481 |
+
if (!$large_import) $wpdb->query("ALTER TABLE {$table} ADD `large_import` ENUM( 'Yes', 'No' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'No';");
|
482 |
+
if (!$root_element) $wpdb->query("ALTER TABLE {$table} ADD `root_element` VARCHAR(255) DEFAULT '';");
|
483 |
+
if (!$processing) $wpdb->query("ALTER TABLE {$table} ADD `processing` BOOL NOT NULL DEFAULT '0';");
|
484 |
+
if (!$triggered) $wpdb->query("ALTER TABLE {$table} ADD `triggered` BOOL NOT NULL DEFAULT '0';");
|
485 |
+
if (!$queue_chunk_number) $wpdb->query("ALTER TABLE {$table} ADD `queue_chunk_number` BIGINT(20) NOT NULL DEFAULT '0';");
|
486 |
+
if (!$current_post_ids) $wpdb->query("ALTER TABLE {$table} ADD `current_post_ids` TEXT NULL DEFAULT '';");
|
487 |
+
if (!$first_import) $wpdb->query("ALTER TABLE {$table} ADD `first_import` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;");
|
488 |
+
if (!$count) $wpdb->query("ALTER TABLE {$table} ADD `count` BIGINT(20) NOT NULL DEFAULT '0';");
|
489 |
+
if (!$imported) $wpdb->query("ALTER TABLE {$table} ADD `imported` BIGINT(20) NOT NULL DEFAULT '0';");
|
490 |
+
if (!$created) $wpdb->query("ALTER TABLE {$table} ADD `created` BIGINT(20) NOT NULL DEFAULT '0';");
|
491 |
+
if (!$updated) $wpdb->query("ALTER TABLE {$table} ADD `updated` BIGINT(20) NOT NULL DEFAULT '0';");
|
492 |
+
if (!$skipped) $wpdb->query("ALTER TABLE {$table} ADD `skipped` BIGINT(20) NOT NULL DEFAULT '0';");
|
493 |
+
if (!$friendly_name) $wpdb->query("ALTER TABLE {$table} ADD `friendly_name` VARCHAR(255) NOT NULL DEFAULT '';");
|
494 |
+
|
495 |
+
$table = $this->getTablePrefix() . 'templates';
|
496 |
+
global $wpdb;
|
497 |
+
$tablefields = $wpdb->get_results("DESCRIBE {$table};");
|
498 |
+
$is_leave_html = false;
|
499 |
+
// Check if field exists
|
500 |
+
foreach ($tablefields as $tablefield) {
|
501 |
+
if ('is_leave_html' == $tablefield->Field) $is_leave_html = true;
|
502 |
+
}
|
503 |
+
if (!$is_leave_html) $wpdb->query("ALTER TABLE {$table} ADD `is_leave_html` TINYINT( 1 ) NOT NULL DEFAULT '0';");
|
504 |
+
|
505 |
+
}
|
506 |
+
|
507 |
/**
|
508 |
* Method returns default import options, main utility of the method is to avoid warnings when new
|
509 |
* option is introduced but already registered imports don't have it
|
515 |
'categories' => '',
|
516 |
'tags' => '',
|
517 |
'tags_delim' => ',',
|
518 |
+
'categories_delim' => ',',
|
519 |
+
'featured_delim' => ',',
|
520 |
+
'atch_delim' => ',',
|
521 |
'post_taxonomies' => array(),
|
522 |
'parent' => '',
|
523 |
'order' => '0',
|
532 |
'custom_value' => array(),
|
533 |
'comment_status' => 'open',
|
534 |
'ping_status' => 'open',
|
535 |
+
'create_draft' => 'no',
|
536 |
+
'author' => '',
|
537 |
'featured_image' => '',
|
538 |
+
'attachments' => '',
|
539 |
'is_import_specified' => 0,
|
540 |
'import_specified' => '',
|
541 |
'is_delete_source' => 0,
|
542 |
'is_cloak' => 0,
|
543 |
'unique_key' => '',
|
544 |
+
'feed_type' => 'auto',
|
545 |
|
546 |
'is_delete_missing' => 0,
|
547 |
+
'is_keep_former_posts' => 'no',
|
548 |
'is_keep_status' => 0,
|
549 |
+
'is_keep_content' => 0,
|
550 |
+
'is_keep_title' => 0,
|
551 |
+
'is_keep_excerpt' => 0,
|
552 |
'is_keep_categories' => 0,
|
553 |
'is_keep_attachments' => 0,
|
554 |
+
'is_keep_images' => 0,
|
555 |
'is_duplicates' => 0,
|
556 |
+
'is_keep_dates' => 0,
|
557 |
+
'is_keep_menu_order' => 0,
|
558 |
+
'records_per_request' => 10,
|
559 |
+
'not_create_records' => 0,
|
560 |
+
'no_create_featured_image' => 0,
|
561 |
|
562 |
'duplicate_indicator' => 'title',
|
563 |
'duplicate_action' => 'keep',
|
|
|
564 |
'is_update_previous' => 0,
|
565 |
'is_scheduled' => '',
|
566 |
+
'scheduled_period' => '',
|
567 |
+
'post_excerpt' => '',
|
568 |
+
'post_slug' => '',
|
569 |
+
'keep_custom_fields' => 0,
|
570 |
+
'keep_custom_fields_specific' => '',
|
571 |
+
'friendly_name' => '',
|
572 |
+
'custom_duplicate_name' => '',
|
573 |
+
'custom_duplicate_value' => '',
|
574 |
+
'duplicate_matching' => 'auto',
|
575 |
+
'create_chunks' => 0,
|
576 |
);
|
577 |
}
|
578 |
|
585 |
|
586 |
$csv = new PMXI_CsvParser($csv_url);
|
587 |
|
588 |
+
$wp_uploads = wp_upload_dir();
|
589 |
+
$tmpname = wp_unique_filename($wp_uploads['path'], str_replace("csv", "xml", basename($csv_url)));
|
590 |
+
$xml_file = $wp_uploads['path'] .'/'. $tmpname;
|
591 |
+
file_put_contents($xml_file, $csv->toXML());
|
592 |
+
return $xml_file;
|
593 |
|
594 |
}
|
595 |
+
|
596 |
+
public static function is_ajax(){
|
597 |
+
return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') ? true : false ;
|
|
|
|
|
|
|
|
|
598 |
}
|
599 |
+
|
600 |
}
|
601 |
|
602 |
PMXI_Plugin::getInstance();
|
readme.txt
CHANGED
@@ -1,36 +1,45 @@
|
|
1 |
-
=== WP All Import ===
|
2 |
Contributors: soflyy
|
3 |
Tags: wordpress, xml, csv, datafeed, import
|
4 |
-
Requires at least: 3.
|
5 |
-
Tested up to: 3.
|
6 |
-
Stable tag:
|
7 |
|
8 |
-
|
9 |
|
10 |
== Description ==
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
= WP All Import Professional Edition =
|
|
|
13 |
|
14 |
-
|
15 |
|
16 |
-
*
|
17 |
|
18 |
-
|
19 |
|
|
|
20 |
|
21 |
-
WP All Import
|
22 |
|
23 |
-
|
|
|
|
|
|
|
|
|
24 |
|
25 |
-
|
26 |
|
27 |
-
* Upload XML/CSV from your computer, or get it from a URL/FTP server
|
28 |
-
* Use XPath to filter a file and only import the entries you want.
|
29 |
-
* Drag & Drop template tags into the WYSIWYG post editor to design your posts and choose what data goes where.
|
30 |
-
* Save options & templates.
|
31 |
-
* Auto-creation of categories based on data in the feed.
|
32 |
-
* Managing of previous imports
|
33 |
|
|
|
34 |
|
35 |
== Premium Support ==
|
36 |
Upgrade to the professional edition of WP All Import for premium support.
|
@@ -47,24 +56,30 @@ Either: -
|
|
47 |
|
48 |
== Frequently Asked Questions ==
|
49 |
|
50 |
-
*What
|
51 |
-
|
|
|
|
|
|
|
52 |
|
53 |
-
*
|
54 |
-
Generally, WP All Import can comfortably handle files of up to 100Mb in most shared hosting environments (GoDaddy, HostGator, etc.). On VPS or dedicated hosting environments, the size of file WP All Import can handle is only limited by the power of the server. When importing very large files it is recommended to split them into chunks and import each chunk individually.
|
55 |
|
56 |
-
|
57 |
-
|
|
|
58 |
|
59 |
== Screenshots ==
|
60 |
|
61 |
1. Choose file.
|
62 |
-
2.
|
63 |
-
3.
|
64 |
-
4.
|
65 |
|
66 |
== Changelog ==
|
67 |
|
|
|
|
|
|
|
68 |
= 2.14 =
|
69 |
* Category list delimiter bug fix
|
70 |
|
1 |
+
=== WP All Import - Import any XML or CSV File to WordPress ===
|
2 |
Contributors: soflyy
|
3 |
Tags: wordpress, xml, csv, datafeed, import
|
4 |
+
Requires at least: 3.5
|
5 |
+
Tested up to: 3.5.1
|
6 |
+
Stable tag: 3.0
|
7 |
|
8 |
+
WP All Import is an extremely powerful plugin that makes it easy to import any XML or CSV file to WordPress.
|
9 |
|
10 |
== Description ==
|
11 |
|
12 |
+
WP All Import is an extremely powerful plugin that makes it easy to import any XML or CSV file to WordPress.
|
13 |
+
|
14 |
+
WP All Import has a four step import process and an intuitive drag & drop interface that makes complicated import tasks simple and fast.
|
15 |
+
|
16 |
+
There are no special requirements that the elements in your file must be laid out in a certain way. WP All Import really can import any XML or CSV file.
|
17 |
+
|
18 |
+
WP All Import can be used for everything from building a store with an affiliate datafeed to displaying live stock quotes or sports scores to building a real estate portal.
|
19 |
+
|
20 |
= WP All Import Professional Edition =
|
21 |
+
[youtube http://www.youtube.com/watch?v=5YYZyYmX3yg /]
|
22 |
|
23 |
+
*WP All Import Pro* is a $99 upgrade that adds the following features to the free version of WP All Import:
|
24 |
|
25 |
+
* Import to Custom Post Types - commonly used to import to Automotiv, OpenHouse, Listings, and WooCommerce, as well as any other theme or plugin that makes use of Custom Post Types.
|
26 |
|
27 |
+
* Cron Job/Recurring Imports - WP All Import pro can check periodically check a file for updates, and add, edit, and delete to the imported posts accordingly.
|
28 |
|
29 |
+
* Import data to Custom Fields - used by many themes, especially those using Custom Post Types - to store data associated with the posts.
|
30 |
|
31 |
+
* Import images to the post media gallery - WP All Import can download images from URLs in an XML or CSV file and put them in the media gallery.
|
32 |
|
33 |
+
* Import files from a URL or FTP server - Download and import files from external websites or FTP servers, even if they are password protected. FTP imports support wildcard patterns, i.e. *.xml, so for example you could download and import all XML files in a certain folder.
|
34 |
+
|
35 |
+
* URL and FTP imports are integrated with the recurring/cron imports feature, so WP All Import can periodically re-download the files and add, edit, and delete posts accordingly.
|
36 |
+
|
37 |
+
* Execution of Custom PHP Functions on data, i.e. use something like [my_function({xpath/to/a/field[1]})] in your template, to pass the value of {xpath/to/a/field[1]} to my_function and display whatever it returns.
|
38 |
|
39 |
+
* Pro version customers also get access to our customer portal with documentation and tutorials, and e-mail technical support.
|
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
+
[Upgrade to the professional edition of WP All Import.](http://www.wpallimport.com/upgrade-to-pro)
|
43 |
|
44 |
== Premium Support ==
|
45 |
Upgrade to the professional edition of WP All Import for premium support.
|
56 |
|
57 |
== Frequently Asked Questions ==
|
58 |
|
59 |
+
*What Size Files Can WP All Import Handle?*
|
60 |
+
With the release of WP All Import version 3, WP All Import can now handle files of any size and any number of records, as long as the web hosting provider can too. Typically, WP All Import can comfortably import files of 100Mb and larger in most shared hosting environments (HostGator, etc). Please see this page for moredetails.
|
61 |
+
|
62 |
+
*What are the benefits of the $99 professional version?*
|
63 |
+
Support for Custom Post Types, Custom Taxonomies, Custom Fields, cron jobs/recurring imports, download and importing of images to the post media gallery, and URL/FTP server uploads.
|
64 |
|
65 |
+
*The answer to all of the following questions is yes:*
|
|
|
66 |
|
67 |
+
Does this really work with ANY XML or CSV file?
|
68 |
+
Can WP All Import get ALL of the data out of the file? Even attributes?
|
69 |
+
Does it work with special character encoding like Hebrew, Arabic, Chinese, etc?
|
70 |
|
71 |
== Screenshots ==
|
72 |
|
73 |
1. Choose file.
|
74 |
+
2. Template designer.
|
75 |
+
3. Post options.
|
76 |
+
4. Manage imports.
|
77 |
|
78 |
== Changelog ==
|
79 |
|
80 |
+
= 3.0 =
|
81 |
+
* Free edition of 3.0 pro release
|
82 |
+
|
83 |
= 2.14 =
|
84 |
* Category list delimiter bug fix
|
85 |
|
schema.php
CHANGED
@@ -33,18 +33,32 @@ CREATE TABLE {$table_prefix}templates (
|
|
33 |
title TEXT,
|
34 |
content LONGTEXT,
|
35 |
is_keep_linebreaks TINYINT(1) NOT NULL DEFAULT 0,
|
|
|
36 |
PRIMARY KEY (id)
|
37 |
) $charset_collate;
|
38 |
CREATE TABLE {$table_prefix}imports (
|
39 |
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
40 |
name VARCHAR(255) NOT NULL DEFAULT '',
|
|
|
41 |
type VARCHAR(32) NOT NULL DEFAULT '',
|
42 |
-
path TEXT,
|
43 |
xpath VARCHAR(255) NOT NULL DEFAULT '',
|
44 |
template LONGTEXT,
|
45 |
options TEXT,
|
46 |
scheduled VARCHAR(64) NOT NULL DEFAULT '',
|
47 |
-
registered_on DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
PRIMARY KEY (id)
|
49 |
) $charset_collate;
|
50 |
CREATE TABLE {$table_prefix}posts (
|
33 |
title TEXT,
|
34 |
content LONGTEXT,
|
35 |
is_keep_linebreaks TINYINT(1) NOT NULL DEFAULT 0,
|
36 |
+
is_leave_html TINYINT(1) NOT NULL DEFAULT 0,
|
37 |
PRIMARY KEY (id)
|
38 |
) $charset_collate;
|
39 |
CREATE TABLE {$table_prefix}imports (
|
40 |
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
41 |
name VARCHAR(255) NOT NULL DEFAULT '',
|
42 |
+
friendly_name VARCHAR(255) NOT NULL DEFAULT '',
|
43 |
type VARCHAR(32) NOT NULL DEFAULT '',
|
44 |
+
path TEXT,
|
45 |
xpath VARCHAR(255) NOT NULL DEFAULT '',
|
46 |
template LONGTEXT,
|
47 |
options TEXT,
|
48 |
scheduled VARCHAR(64) NOT NULL DEFAULT '',
|
49 |
+
registered_on DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
|
50 |
+
large_import ENUM('Yes','No') NOT NULL DEFAULT 'No',
|
51 |
+
root_element VARCHAR(255) DEFAULT '',
|
52 |
+
processing BOOL NOT NULL DEFAULT '0',
|
53 |
+
triggered BOOL NOT NULL DEFAULT '0',
|
54 |
+
queue_chunk_number BIGINT(20) NOT NULL DEFAULT '0',
|
55 |
+
current_post_ids TEXT NULL DEFAULT '',
|
56 |
+
first_import TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
57 |
+
count BIGINT(20) NOT NULL DEFAULT '0',
|
58 |
+
imported BIGINT(20) NOT NULL DEFAULT '0',
|
59 |
+
created BIGINT(20) NOT NULL DEFAULT '0',
|
60 |
+
updated BIGINT(20) NOT NULL DEFAULT '0',
|
61 |
+
skipped BIGINT(20) NOT NULL DEFAULT '0',
|
62 |
PRIMARY KEY (id)
|
63 |
) $charset_collate;
|
64 |
CREATE TABLE {$table_prefix}posts (
|
screenshot-1.png
CHANGED
Binary file
|
screenshot-2.png
CHANGED
Binary file
|
screenshot-3.png
CHANGED
Binary file
|
screenshot-4.png
CHANGED
Binary file
|
static/css/admin.css
CHANGED
@@ -7,9 +7,9 @@
|
|
7 |
margin-bottom: 15px;
|
8 |
}
|
9 |
.pmxi_plugin a.button {
|
10 |
-
padding: 5px 10px;
|
11 |
margin: 1px;
|
12 |
-
font-weight: bold
|
13 |
}
|
14 |
.pmxi_plugin a.help {
|
15 |
overflow: hidden;
|
@@ -37,6 +37,7 @@
|
|
37 |
}
|
38 |
.pmxi_plugin .progress-msg {
|
39 |
font-style: italic;
|
|
|
40 |
}
|
41 |
.pmxi_plugin .inner-content {
|
42 |
max-width: 700px;
|
@@ -46,6 +47,11 @@
|
|
46 |
background-repeat: no-repeat;
|
47 |
background-position: center;
|
48 |
}
|
|
|
|
|
|
|
|
|
|
|
49 |
.pmxi_plugin a.add-new {
|
50 |
font-size: 18px;
|
51 |
background-color: #eee;
|
@@ -67,15 +73,20 @@
|
|
67 |
color: #000;
|
68 |
}
|
69 |
.pmxi_plugin div.input {
|
70 |
-
line-height: 25px;
|
71 |
-
height: 25px
|
|
|
72 |
}
|
73 |
.pmxi_plugin div.input > * {
|
74 |
vertical-align: middle;
|
75 |
}
|
|
|
|
|
|
|
|
|
76 |
.pmxi_plugin .note {
|
77 |
color: #666666;
|
78 |
-
font-size:
|
79 |
}
|
80 |
.pmxi_plugin div.sub {
|
81 |
padding-left: 20px;
|
@@ -90,7 +101,7 @@
|
|
90 |
}
|
91 |
.pmxi_plugin table.layout td {
|
92 |
vertical-align: top;
|
93 |
-
border: none;
|
94 |
}
|
95 |
.pmxi_plugin table.layout td.left {
|
96 |
min-width: 490px;
|
@@ -98,7 +109,7 @@
|
|
98 |
}
|
99 |
.pmxi_plugin table.layout td.right {
|
100 |
padding: 0px 0 16px 20px;
|
101 |
-
width:
|
102 |
min-width: 260px;
|
103 |
}
|
104 |
.pmxi_plugin table.layout td.left > h2:first-child {
|
@@ -121,7 +132,8 @@
|
|
121 |
|
122 |
/*@+ Choose File forms */
|
123 |
.pmxi_plugin form.choose-file {
|
124 |
-
padding-top:
|
|
|
125 |
}
|
126 |
.pmxi_plugin form.choose-file h3 {
|
127 |
margin-bottom: 5px;
|
@@ -136,7 +148,7 @@
|
|
136 |
}
|
137 |
.pmxi_plugin form.choose-file input.regular-text,
|
138 |
.pmxi_plugin form.choose-file select.regular-text {
|
139 |
-
width:
|
140 |
}
|
141 |
.pmxi_plugin #wpcontent form.choose-file select[name="file"],
|
142 |
.pmxi_plugin #wpcontent form.choose-file select[name="reimport"] {
|
@@ -162,11 +174,9 @@
|
|
162 |
.pmxi_plugin form.template.edit {
|
163 |
/*width: 700px;*/
|
164 |
}
|
165 |
-
.pmxi_plugin form.template .load-template {
|
166 |
display: block;
|
167 |
-
|
168 |
-
padding-top: 7px;
|
169 |
-
font-size: 12px;
|
170 |
}
|
171 |
.pmxi_plugin form.template .load-template select {
|
172 |
width: 126px;
|
@@ -244,6 +254,7 @@
|
|
244 |
}
|
245 |
.pmxi_plugin .post-type-options table.form-table select {
|
246 |
max-width: 300px;
|
|
|
247 |
}
|
248 |
.pmxi_plugin table.form-table thead td {
|
249 |
font-weight: bold;
|
@@ -257,24 +268,41 @@
|
|
257 |
/*@*/
|
258 |
|
259 |
/*@+ XML representation */
|
260 |
-
.pmxi_plugin .tag {
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
-
|
265 |
-
|
266 |
-
border-radius: 4px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
267 |
}
|
268 |
.pmxi_plugin .tag .title {
|
269 |
font-weight: bold;
|
270 |
padding: 6px 8px;
|
271 |
color: #464646;
|
272 |
-
background:
|
273 |
font-size: 12px;
|
274 |
}
|
275 |
.pmxi_plugin .tag .xml {
|
276 |
-
max-height:
|
277 |
overflow: auto;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
278 |
}
|
279 |
.pmxi_plugin .tag .navigation {
|
280 |
float: right;
|
@@ -287,6 +315,15 @@
|
|
287 |
text-decoration: none;
|
288 |
}
|
289 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
290 |
.xml {
|
291 |
padding-left: 15px;
|
292 |
}
|
@@ -464,16 +501,15 @@ table.xml table {
|
|
464 |
}
|
465 |
|
466 |
.pmxi_plugin #process{ display:none; }
|
467 |
-
.pmxi_plugin .load-options{ float:right; font-size:13px; }
|
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-
|
476 |
-
background-position:
|
477 |
}
|
478 |
.sortable li{ position: relative;}
|
479 |
.pmxi_plugin ol{
|
@@ -481,24 +517,449 @@ table.xml table {
|
|
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 |
-
|
493 |
-
|
494 |
-
|
|
|
495 |
}
|
496 |
|
497 |
.pmxi_plugin .remove-ico{
|
498 |
background: url("../img/ico-remove.png") no-repeat;
|
499 |
top:1px;
|
500 |
-
right:-
|
501 |
position: absolute;
|
502 |
}
|
503 |
|
504 |
-
.pmxi_plugin .hidden{ display: none; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
margin-bottom: 15px;
|
8 |
}
|
9 |
.pmxi_plugin a.button {
|
10 |
+
/*padding: 5px 10px;
|
11 |
margin: 1px;
|
12 |
+
font-weight: bold;*/
|
13 |
}
|
14 |
.pmxi_plugin a.help {
|
15 |
overflow: hidden;
|
37 |
}
|
38 |
.pmxi_plugin .progress-msg {
|
39 |
font-style: italic;
|
40 |
+
display: none;
|
41 |
}
|
42 |
.pmxi_plugin .inner-content {
|
43 |
max-width: 700px;
|
47 |
background-repeat: no-repeat;
|
48 |
background-position: center;
|
49 |
}
|
50 |
+
.pmxi_plugin .preload {
|
51 |
+
background-image: url("../img/loading.png");
|
52 |
+
background-repeat: no-repeat;
|
53 |
+
background-position: 50% 200px;
|
54 |
+
}
|
55 |
.pmxi_plugin a.add-new {
|
56 |
font-size: 18px;
|
57 |
background-color: #eee;
|
73 |
color: #000;
|
74 |
}
|
75 |
.pmxi_plugin div.input {
|
76 |
+
/*line-height: 25px;
|
77 |
+
height: 25px;*/
|
78 |
+
min-height: 21px;
|
79 |
}
|
80 |
.pmxi_plugin div.input > * {
|
81 |
vertical-align: middle;
|
82 |
}
|
83 |
+
.pmxi_plugin .options input[type=text], .pmxi_plugin .options select {
|
84 |
+
background: #fafafa !important;
|
85 |
+
border: 1px solid #aaa !important;
|
86 |
+
}
|
87 |
.pmxi_plugin .note {
|
88 |
color: #666666;
|
89 |
+
font-size: 9px;
|
90 |
}
|
91 |
.pmxi_plugin div.sub {
|
92 |
padding-left: 20px;
|
101 |
}
|
102 |
.pmxi_plugin table.layout td {
|
103 |
vertical-align: top;
|
104 |
+
border: none;
|
105 |
}
|
106 |
.pmxi_plugin table.layout td.left {
|
107 |
min-width: 490px;
|
109 |
}
|
110 |
.pmxi_plugin table.layout td.right {
|
111 |
padding: 0px 0 16px 20px;
|
112 |
+
width: 25%;
|
113 |
min-width: 260px;
|
114 |
}
|
115 |
.pmxi_plugin table.layout td.left > h2:first-child {
|
132 |
|
133 |
/*@+ Choose File forms */
|
134 |
.pmxi_plugin form.choose-file {
|
135 |
+
padding-top: 20px;
|
136 |
+
position: relative;
|
137 |
}
|
138 |
.pmxi_plugin form.choose-file h3 {
|
139 |
margin-bottom: 5px;
|
148 |
}
|
149 |
.pmxi_plugin form.choose-file input.regular-text,
|
150 |
.pmxi_plugin form.choose-file select.regular-text {
|
151 |
+
width: 100%;
|
152 |
}
|
153 |
.pmxi_plugin #wpcontent form.choose-file select[name="file"],
|
154 |
.pmxi_plugin #wpcontent form.choose-file select[name="reimport"] {
|
174 |
.pmxi_plugin form.template.edit {
|
175 |
/*width: 700px;*/
|
176 |
}
|
177 |
+
.pmxi_plugin form.template .load-template {
|
178 |
display: block;
|
179 |
+
font-size: 12px;
|
|
|
|
|
180 |
}
|
181 |
.pmxi_plugin form.template .load-template select {
|
182 |
width: 126px;
|
254 |
}
|
255 |
.pmxi_plugin .post-type-options table.form-table select {
|
256 |
max-width: 300px;
|
257 |
+
width:300px;
|
258 |
}
|
259 |
.pmxi_plugin table.form-table thead td {
|
260 |
font-weight: bold;
|
268 |
/*@*/
|
269 |
|
270 |
/*@+ XML representation */
|
271 |
+
.pmxi_plugin .tag {
|
272 |
+
background-color: #fff;
|
273 |
+
position: fixed;
|
274 |
+
width:22%;
|
275 |
+
margin-top: 45px;
|
276 |
+
border-top: 1px solid #DFDFDF;
|
277 |
+
-moz-border-radius-topleft: 4px;
|
278 |
+
-webkit-border-top-left-radius: 4px;
|
279 |
+
border-top-left-radius: 4px;
|
280 |
+
-moz-border-radius-topright: 4px;
|
281 |
+
-webkit-border-top-right-radius: 4px;
|
282 |
+
border-top-right-radius: 4px;
|
283 |
+
}
|
284 |
+
|
285 |
+
.pmxi_plugin .options .tag{
|
286 |
+
margin-top: 0px;
|
287 |
}
|
288 |
.pmxi_plugin .tag .title {
|
289 |
font-weight: bold;
|
290 |
padding: 6px 8px;
|
291 |
color: #464646;
|
292 |
+
background: #DFDFDF;
|
293 |
font-size: 12px;
|
294 |
}
|
295 |
.pmxi_plugin .tag .xml {
|
296 |
+
max-height: 525px;
|
297 |
overflow: auto;
|
298 |
+
border: 1px solid #DFDFDF;
|
299 |
+
border-top:none;
|
300 |
+
-moz-border-radius-bottomright: 4px;
|
301 |
+
-webkit-border-bottom-right-radius: 4px;
|
302 |
+
border-bottom-right-radius: 4px;
|
303 |
+
-moz-border-radius-bottomleft: 4px;
|
304 |
+
-webkit-border-bottom-left-radius: 4px;
|
305 |
+
border-bottom-left-radius: 4px;
|
306 |
}
|
307 |
.pmxi_plugin .tag .navigation {
|
308 |
float: right;
|
315 |
text-decoration: none;
|
316 |
}
|
317 |
|
318 |
+
@media screen and (max-height: 700px) {
|
319 |
+
.pmxi_plugin .tag {
|
320 |
+
height:300px;
|
321 |
+
}
|
322 |
+
.pmxi_plugin .tag .xml {
|
323 |
+
max-height: 265px;
|
324 |
+
}
|
325 |
+
}
|
326 |
+
|
327 |
.xml {
|
328 |
padding-left: 15px;
|
329 |
}
|
501 |
}
|
502 |
|
503 |
.pmxi_plugin #process{ display:none; }
|
504 |
+
.pmxi_plugin .load-options{ float:right; font-size:13px; position: relative; top: -30px; }
|
505 |
+
.pmxi_plugin form.options table.layout td.right{
|
|
|
506 |
width: 25%;
|
507 |
}
|
508 |
.pmxi_plugin .drag-element{
|
509 |
background: url("../img/drag.png") top right no-repeat;
|
510 |
cursor: pointer;
|
511 |
+
padding-left: 25px;
|
512 |
+
background-position: 0px 1px;
|
513 |
}
|
514 |
.sortable li{ position: relative;}
|
515 |
.pmxi_plugin ol{
|
517 |
list-style: none;
|
518 |
}
|
519 |
.pmxi_plugin .no-margin{ margin:0px; }
|
520 |
+
.pmxi_plugin .icon-item, .pmxi_plugin .add-new-custom{
|
521 |
+
display: inline-block;
|
522 |
width: 16px;
|
523 |
height: 16px;
|
524 |
margin: 0px 3px;
|
525 |
}
|
526 |
+
.pmxi_plugin .add-new-ico, .pmxi_plugin .add-new-custom{
|
527 |
+
background: url("../img/ico-add-new.png") no-repeat 0px 4px;
|
528 |
+
width:70px;
|
529 |
+
height:25px;
|
530 |
+
padding-left: 15px;
|
531 |
+
color:#21759B;
|
532 |
}
|
533 |
|
534 |
.pmxi_plugin .remove-ico{
|
535 |
background: url("../img/ico-remove.png") no-repeat;
|
536 |
top:1px;
|
537 |
+
right:-4px;
|
538 |
position: absolute;
|
539 |
}
|
540 |
|
541 |
+
.pmxi_plugin .hidden{ display: none; }
|
542 |
+
|
543 |
+
.pmxi_plugin .fs11 { font-size:11px; }
|
544 |
+
|
545 |
+
.pmxi_plugin .rel { position: relative; }
|
546 |
+
|
547 |
+
#type_meta_select{ margin-bottom: 10px; height:1.8em; }
|
548 |
+
|
549 |
+
.upload_process{
|
550 |
+
border: none;
|
551 |
+
padding: 1px;
|
552 |
+
}
|
553 |
+
|
554 |
+
#large_import_xpath{ display:none; }
|
555 |
+
#large_import{ margin:0px 5px; }
|
556 |
+
#download_pmxi_log{
|
557 |
+
cursor: pointer;
|
558 |
+
margin: 5px 0;
|
559 |
+
display: none;
|
560 |
+
}
|
561 |
+
.pmxi_plugin .import_process_bar, .pmxi_plugin .import_percent{
|
562 |
+
display: none;
|
563 |
+
}
|
564 |
+
/*.pmxi_plugin .import_progress{
|
565 |
+
font-size: 14px !important;
|
566 |
+
}*/
|
567 |
+
.pmxi_plugin #processbar{
|
568 |
+
text-align: center;
|
569 |
+
visibility: hidden;
|
570 |
+
height: 37px;
|
571 |
+
padding-top: 18px;
|
572 |
+
margin-bottom: 20px;
|
573 |
+
border: 1px solid #AAAAAA;
|
574 |
+
color: #222222;
|
575 |
+
position: relative;
|
576 |
+
}
|
577 |
+
.pmxi_plugin #processbar div{
|
578 |
+
background: #aaa;
|
579 |
+
height: 55px;
|
580 |
+
width: 0%;
|
581 |
+
position: absolute;
|
582 |
+
opacity: 0.5;
|
583 |
+
top:0;
|
584 |
+
}
|
585 |
+
.pmxi_plugin #import_progress{
|
586 |
+
color: #000000;
|
587 |
+
font-size: 13px;
|
588 |
+
font-weight: bold;
|
589 |
+
opacity: 1;
|
590 |
+
}
|
591 |
+
.pmxi_plugin #right_progress{ float:right; padding-right: 5px; }
|
592 |
+
.pmxi_plugin #left_progress{ float:left; padding-left: 5px; }
|
593 |
+
.pmxi_plugin #existing_meta_keys{
|
594 |
+
margin-bottom: 10px;
|
595 |
+
padding: 2px;
|
596 |
+
width: 580px;
|
597 |
+
}
|
598 |
+
.pmxi_plugin #pmxi_tabs{
|
599 |
+
display: none;
|
600 |
+
padding-bottom: 20px;
|
601 |
+
-moz-border-radius: 4px;
|
602 |
+
-khtml-border-radius: 4px;
|
603 |
+
-webkit-border-radius: 4px;
|
604 |
+
border-radius: 4px;
|
605 |
+
}
|
606 |
+
.pmxi_plugin .ui-widget-header{
|
607 |
+
-moz-border-radius: 4px;
|
608 |
+
-khtml-border-radius: 4px;
|
609 |
+
-webkit-border-radius: 4px;
|
610 |
+
border-radius: 4px;
|
611 |
+
}
|
612 |
+
.pmxi_plugin .ui-tabs .ui-tabs-nav li{
|
613 |
+
-moz-border-top-left-radius: 4px;
|
614 |
+
-khtml-border-top-left-radius: 4px;
|
615 |
+
-webkit-border-top-left-radius: 4px;
|
616 |
+
border-top-left-radius: 4px;
|
617 |
+
-moz-border-top-right-radius: 4px;
|
618 |
+
-khtml-border-top-right-radius: 4px;
|
619 |
+
-webkit-border-top-right-radius: 4px;
|
620 |
+
border-top-right-radius: 4px;
|
621 |
+
}
|
622 |
+
/*.pmxi_plugin .ui-widget-header{
|
623 |
+
background: #F2FBD9;
|
624 |
+
border: 1px solid #F2FBD9;
|
625 |
+
}
|
626 |
+
.pmxi_plugin .ui-state-default{
|
627 |
+
border:none;
|
628 |
+
font-size: 12px;
|
629 |
+
font-weight: bold;
|
630 |
+
background: #F2FBD9;
|
631 |
+
}
|
632 |
+
.pmxi_plugin .ui-state-active{
|
633 |
+
background: #fff;
|
634 |
+
}
|
635 |
+
.pmxi_plugin .ui-tabs{
|
636 |
+
padding: 0px;
|
637 |
+
}*/
|
638 |
+
#select-files{
|
639 |
+
font-size: 11px !important;
|
640 |
+
height:25px;
|
641 |
+
}
|
642 |
+
.pmxi_plugin .progress{
|
643 |
+
position: relative;
|
644 |
+
visibility: hidden;
|
645 |
+
color: #009039;
|
646 |
+
font-size: 13px;
|
647 |
+
font-weight: bold;
|
648 |
+
margin-top: 10px;
|
649 |
+
width: 100%;
|
650 |
+
text-align: center;
|
651 |
+
border:1px solid #4297D7;
|
652 |
+
-moz-border-radius: 4px;
|
653 |
+
-khtml-border-radius: 4px;
|
654 |
+
-webkit-border-radius: 4px;
|
655 |
+
border-radius: 4px;
|
656 |
+
}
|
657 |
+
.pmxi_plugin #progressbar{
|
658 |
+
border: medium none;
|
659 |
+
left: 0;
|
660 |
+
position: absolute;
|
661 |
+
text-align: center;
|
662 |
+
top: 8px;
|
663 |
+
width: 100%;
|
664 |
+
font-size: 12px;
|
665 |
+
color:#333;
|
666 |
+
}
|
667 |
+
.pmxi_plugin #file_name{
|
668 |
+
font-size: 16px;
|
669 |
+
font-weight: bold;
|
670 |
+
margin-left: 10px;
|
671 |
+
float: right;
|
672 |
+
}
|
673 |
+
.pmxi_plugin .ui-progressbar .ui-progressbar-value { /*background-image: url("../img/progress_animated.gif");*/ }
|
674 |
+
.pmxi_plugin form.choose-file .submit-buttons{
|
675 |
+
/*bottom: -125px;
|
676 |
+
position: absolute;
|
677 |
+
right: -18px; */
|
678 |
+
}
|
679 |
+
.pmxi_plugin form#basic .submit-buttons{
|
680 |
+
display: none;
|
681 |
+
}
|
682 |
+
.pmxi_plugin fieldset{
|
683 |
+
padding: 20px;
|
684 |
+
width:auto;
|
685 |
+
}
|
686 |
+
.pmxi_plugin .right fieldset{
|
687 |
+
padding: 15px;
|
688 |
+
}
|
689 |
+
.pmxi_plugin .right fieldset input{
|
690 |
+
max-width:none;
|
691 |
+
padding:6px;
|
692 |
+
margin:0px
|
693 |
+
}
|
694 |
+
.pmxi_plugin .right a{
|
695 |
+
text-decoration: underline;
|
696 |
+
}
|
697 |
+
.pmxi_plugin fieldset legend{
|
698 |
+
padding: 0px 5px;
|
699 |
+
font-weight: bold;
|
700 |
+
}
|
701 |
+
.pmxi_plugin .options fieldset legend{
|
702 |
+
font-size: 1.17em;
|
703 |
+
}
|
704 |
+
.pmxi_plugin .matches_count{
|
705 |
+
font-weight: bold;
|
706 |
+
color:#33AA28;
|
707 |
+
}
|
708 |
+
.pmxi_plugin .xpath_help{
|
709 |
+
/*bottom: -40px;*/
|
710 |
+
position: relative;
|
711 |
+
text-align: center;
|
712 |
+
}
|
713 |
+
.pmxi_plugin .btns, .pmxi_plugin .btns input, .pmxi_plugin .btns a{
|
714 |
+
float: right;
|
715 |
+
}
|
716 |
+
.pmxi_plugin .btns input{
|
717 |
+
height: 19px;
|
718 |
+
margin-left: 5px;
|
719 |
+
padding-top: 0;
|
720 |
+
}
|
721 |
+
.pmxi_plugin .btns a{
|
722 |
+
font-weight: bold;
|
723 |
+
margin: 0 5px;
|
724 |
+
padding: 4px 10px;
|
725 |
+
width:70px;
|
726 |
+
text-align: center;
|
727 |
+
}
|
728 |
+
.pmxi_plugin .col3{
|
729 |
+
border-right: 1px solid #CCCCCC;
|
730 |
+
float: left;
|
731 |
+
height: 265px;
|
732 |
+
width:30%;
|
733 |
+
margin-bottom: 10px;
|
734 |
+
padding: 0 1%;
|
735 |
+
}
|
736 |
+
.pmxi_plugin .col3.last{
|
737 |
+
border: none;
|
738 |
+
}
|
739 |
+
.pmxi_plugin .col3 > div{
|
740 |
+
margin-left: 20px;
|
741 |
+
}
|
742 |
+
.pmxi_plugin .col2{
|
743 |
+
float: left;
|
744 |
+
width: 50%;
|
745 |
+
}
|
746 |
+
.pmxi_plugin .col2 fieldset{
|
747 |
+
border: 1px solid #CCCCCC;
|
748 |
+
margin: 0 5px;
|
749 |
+
padding: 5px 2% 5px 5px;
|
750 |
+
text-align: center;
|
751 |
+
}
|
752 |
+
.pmxi_plugin input.small{
|
753 |
+
width:25px;
|
754 |
+
text-align: center;
|
755 |
+
}
|
756 |
+
.pmxi_plugin .post_taxonomy{
|
757 |
+
margin-bottom: 15px;
|
758 |
+
overflow: hidden;
|
759 |
+
padding-bottom: 15px;
|
760 |
+
}
|
761 |
+
.pmxi_plugin .post_taxonomy .delim{
|
762 |
+
padding-left: 25px;
|
763 |
+
}
|
764 |
+
.pmxi_plugin .post_taxonomy .delim .add-new-ico{
|
765 |
+
float: right;
|
766 |
+
margin-right: 35px;
|
767 |
+
margin-top: 5px;
|
768 |
+
}
|
769 |
+
.pmxi_plugin .post_taxonomy ol.ui-sortable{
|
770 |
+
padding-right: 0px;
|
771 |
+
}
|
772 |
+
.pmxi_plugin .optionsset{
|
773 |
+
border:1px solid #ccc;
|
774 |
+
}
|
775 |
+
.pmxi_plugin .action.remove{
|
776 |
+
display: block;
|
777 |
+
position: relative;
|
778 |
+
}
|
779 |
+
.pmxi_plugin .action.remove a{
|
780 |
+
background: url("../img/ico-remove.png") no-repeat scroll 0 0 transparent;
|
781 |
+
height: 16px;
|
782 |
+
position: absolute;
|
783 |
+
right: -10px;
|
784 |
+
width: 16px;
|
785 |
+
}
|
786 |
+
.pmxi_plugin .switcher-target-is_keep_former_posts{
|
787 |
+
padding-left: 25px;
|
788 |
+
}
|
789 |
+
.pmxi_plugin form.options{
|
790 |
+
position: relative;
|
791 |
+
}
|
792 |
+
.pmxi_plugin .options_buttons{
|
793 |
+
bottom: -75px;
|
794 |
+
display: block;
|
795 |
+
position: absolute;
|
796 |
+
right: 0;
|
797 |
+
}
|
798 |
+
.pmxi-button{
|
799 |
+
border: 1px solid #BBBBBB;
|
800 |
+
color: #464646;
|
801 |
+
cursor: pointer;
|
802 |
+
font-size: 18px !important;
|
803 |
+
margin-left: 10px;
|
804 |
+
padding: 15px 25px;
|
805 |
+
text-decoration: none;
|
806 |
+
-moz-border-radius: 3px;
|
807 |
+
-khtml-border-radius: 3px;
|
808 |
+
-webkit-border-radius: 3px;
|
809 |
+
border-radius: 3px;
|
810 |
+
}
|
811 |
+
.pmxi-button:hover{
|
812 |
+
background: #dfdfdf;
|
813 |
+
}
|
814 |
+
.pmxi_plugin .ui-state-default a{
|
815 |
+
font-size: 13px !important;
|
816 |
+
}
|
817 |
+
.pmxi_plugin .preview{
|
818 |
+
float:none;
|
819 |
+
text-decoration: none;
|
820 |
+
}
|
821 |
+
.pmxi_plugin .template-sidebar .tag{
|
822 |
+
max-height:550px;
|
823 |
+
}
|
824 |
+
.pmxi_plugin .options .submit-buttons{
|
825 |
+
float: right;
|
826 |
+
position: relative;
|
827 |
+
text-align: right;
|
828 |
+
top: 30px;
|
829 |
+
right:-18px;
|
830 |
+
}
|
831 |
+
.pmxi_plugin .back{
|
832 |
+
font-size: 16px;
|
833 |
+
color:#21759B;
|
834 |
+
}
|
835 |
+
.pmxi_plugin .separated_by{
|
836 |
+
float: right;
|
837 |
+
font-size: 12px;
|
838 |
+
color: #999999;
|
839 |
+
margin-right: 20px;
|
840 |
+
}
|
841 |
+
.pmxi_plugin .delim > label{
|
842 |
+
color: #999999;
|
843 |
+
font-size: 11px;
|
844 |
+
}
|
845 |
+
.pmxi_plugin .optionsset > table{
|
846 |
+
border-bottom: 1px solid #CCCCCC;
|
847 |
+
margin-bottom: 20px;
|
848 |
+
width: 100%;
|
849 |
+
}
|
850 |
+
/* Log Bar - Step 5 */
|
851 |
+
.pmxi_plugin #logwrapper{
|
852 |
+
border: 1px solid #aaa;
|
853 |
+
margin-bottom: 20px;
|
854 |
+
}
|
855 |
+
.pmxi_plugin #logbar{
|
856 |
+
padding: 5px 0px;
|
857 |
+
text-align: center;
|
858 |
+
margin: 10px 0px;
|
859 |
+
border: 1px solid #aaa;
|
860 |
+
overflow: auto;
|
861 |
+
}
|
862 |
+
.pmxi_plugin .optionsset > table:last-child{
|
863 |
+
border: none;
|
864 |
+
}
|
865 |
+
.pmxi_plugin #download_log_separator, .pmxi_plugin #download_log{
|
866 |
+
display: none;
|
867 |
+
}
|
868 |
+
.pmxi_plugin #loglist{
|
869 |
+
border: 1px solid #AAAAAA;
|
870 |
+
height: 400px;
|
871 |
+
overflow: auto;
|
872 |
+
}
|
873 |
+
.pmxi_plugin #loglist > p{
|
874 |
+
margin: 0;
|
875 |
+
padding: 3px 5px;
|
876 |
+
}
|
877 |
+
.pmxi_plugin #loglist > p.odd{
|
878 |
+
background: #dfdfdf;
|
879 |
+
}
|
880 |
+
.pmxi_plugin #process_notice{
|
881 |
+
color: red;
|
882 |
+
text-align: center;
|
883 |
+
}
|
884 |
+
.pmxi_plugin #reimported_notify{
|
885 |
+
border: 1px solid #AFAFAF;
|
886 |
+
margin-bottom: 20px;
|
887 |
+
padding: 10px 20px;
|
888 |
+
}
|
889 |
+
.pmxi_plugin #reimported_notify p span{
|
890 |
+
color:#ccc;
|
891 |
+
}
|
892 |
+
.pmxi_plugin .action_buttons{
|
893 |
+
overflow: hidden;
|
894 |
+
clear: both;
|
895 |
+
padding-bottom: 10px;
|
896 |
+
}
|
897 |
+
/*.pmxi_plugin .action_buttons a{
|
898 |
+
border: 1px solid #BBBBBB;
|
899 |
+
-moz-border-radius: 3px;
|
900 |
+
-khtml-border-radius: 3px;
|
901 |
+
-webkit-border-radius: 3px;
|
902 |
+
border-radius: 3px;
|
903 |
+
color: #464646;
|
904 |
+
cursor: pointer;
|
905 |
+
font-size: 18px !important;
|
906 |
+
margin-right: 10px;
|
907 |
+
padding: 15px 25px;
|
908 |
+
text-decoration: none;
|
909 |
+
display: block;
|
910 |
+
width:25px;
|
911 |
+
float: left;
|
912 |
+
}
|
913 |
+
.pmxi_plugin .action_buttons a:hover{
|
914 |
+
background: #dfdfdf;
|
915 |
+
}*/
|
916 |
+
.pmxi_plugin #current_element{
|
917 |
+
color:green;
|
918 |
+
}
|
919 |
+
.pmxi_plugin #current_xml{ display: none;}
|
920 |
+
.pmxi_plugin #goto_element{
|
921 |
+
display: block;
|
922 |
+
float: left;
|
923 |
+
height: 47px;
|
924 |
+
margin-right: 10px;
|
925 |
+
width: 70px !important;
|
926 |
+
min-width: 70px;
|
927 |
+
text-align: center;
|
928 |
+
font-size: 18px;
|
929 |
+
}
|
930 |
+
.pmxi_plugin .choose-elements table tbody tr td{
|
931 |
+
overflow: hidden;
|
932 |
+
}
|
933 |
+
.pmxi_plugin #plupload-ui h3{
|
934 |
+
float: left;
|
935 |
+
font-size: 13px;
|
936 |
+
font-weight: normal;
|
937 |
+
margin-bottom: 0;
|
938 |
+
margin-top: 8px;
|
939 |
+
}
|
940 |
+
.pmxi_plugin #wp-content-media-buttons{
|
941 |
+
display: none;
|
942 |
+
}
|
943 |
+
.pmxi_plugin label{
|
944 |
+
-webkit-touch-callout: none;
|
945 |
+
-webkit-user-select: none;
|
946 |
+
-khtml-user-select: none;
|
947 |
+
-moz-user-select: none;
|
948 |
+
-ms-user-select: none;
|
949 |
+
user-select: none;
|
950 |
+
}
|
951 |
+
.pmxi_plugin .large_button{
|
952 |
+
margin-left: 10px;
|
953 |
+
padding: 15px 25px;
|
954 |
+
border: 1px solid #C5DBEC;
|
955 |
+
}
|
956 |
+
.pmxi_plugin .drag-element .assign_post{
|
957 |
+
float: left;
|
958 |
+
}
|
959 |
+
.pmxi_plugin .drag-element .widefat{
|
960 |
+
margin-left: 1%;
|
961 |
+
width: 90%;
|
962 |
+
}
|
963 |
+
.pmxi_plugin .upgrade_link{
|
964 |
+
color: #21759B;
|
965 |
+
}
|
static/img/loading.gif
DELETED
Binary file
|
static/img/loading.png
ADDED
Binary file
|
static/img/progress_animated.gif
ADDED
Binary file
|
static/js/admin.js
CHANGED
@@ -7,8 +7,7 @@
|
|
7 |
// fix layout position
|
8 |
setTimeout(function () {
|
9 |
$('table.layout').length && $('table.layout td.left h2:first-child').css('margin-top', $('.wrap').offset().top - $('table.layout').offset().top);
|
10 |
-
}, 10);
|
11 |
-
|
12 |
|
13 |
// help icons
|
14 |
$('a.help').tipsy({
|
@@ -109,6 +108,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();
|
@@ -154,7 +154,7 @@
|
|
154 |
return false;
|
155 |
});
|
156 |
// options form: auto submit when `load options` checkbox is checked
|
157 |
-
$('
|
158 |
if ($(this).is(':checked')) $(this).parents('form').submit();
|
159 |
});
|
160 |
// options form: auto submit when `reset options` checkbox is checked
|
@@ -198,7 +198,7 @@
|
|
198 |
if (action.init) {
|
199 |
this.data('initialized', true);
|
200 |
// add expander
|
201 |
-
this.find('.xml-expander').click
|
202 |
var method;
|
203 |
if ('-' == $(this).text()) {
|
204 |
$(this).text('+');
|
@@ -279,7 +279,7 @@
|
|
279 |
}
|
280 |
});
|
281 |
|
282 |
-
if ($('#content').length) tinymce.dom.Event.add('wp-content-editor-container', 'click', function(e) {
|
283 |
if (dblclickbuf.selected)
|
284 |
{
|
285 |
tinyMCE.activeEditor.selection.setContent(dblclickbuf.value);
|
@@ -291,7 +291,11 @@
|
|
291 |
|
292 |
this.find('.xml-tag.opening > .xml-tag-name, .xml-attr-name').each(function () {
|
293 |
var $this = $(this);
|
294 |
-
var xpath = '
|
|
|
|
|
|
|
|
|
295 |
|
296 |
$this.mouseover(function (e) {
|
297 |
$drag.val(xpath).offset({left: $this.offset().left - 2, top: $this.offset().top - 2}).width(_w = $this.width() + 4).height($this.height() + 4);
|
@@ -305,23 +309,53 @@
|
|
305 |
$('form.choose-elements').each(function () {
|
306 |
var $form = $(this);
|
307 |
$form.find('.xml').xml();
|
308 |
-
var $input = $form.find('input[name="xpath"]');
|
309 |
-
$form.find('
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
310 |
if ($form.hasClass('loading')) return; // do nothing if selecting operation is currently under way
|
311 |
$input.val($(this).parents('.xml-element').first().attr('title').replace(/\[\d+\]$/, '')).change();
|
312 |
});
|
313 |
var xpathChanged = function () {
|
314 |
-
if ($input.val() == $input.data('checkedValue')) return;
|
315 |
-
$
|
|
|
|
|
|
|
|
|
316 |
$form.find('.xml-element.selected').removeClass('selected'); // clear current selection
|
317 |
// request server to return elements which correspond to xpath entered
|
318 |
$input.attr('readonly', true).unbind('change', xpathChanged).data('checkedValue', $input.val());
|
319 |
-
$('
|
320 |
-
|
|
|
|
|
321 |
$form.removeClass('loading');
|
|
|
322 |
});
|
323 |
};
|
324 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
325 |
$input.keyup(function (e) {
|
326 |
if (13 == e.keyCode) $(this).change();
|
327 |
});
|
@@ -366,13 +400,23 @@
|
|
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 ($('
|
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 ($('
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
376 |
});
|
377 |
|
378 |
$('.sortable').find('.remove-ico').live('click', function(){
|
@@ -384,17 +428,118 @@
|
|
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 (
|
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 |
-
|
|
|
|
|
|
|
|
|
397 |
|
|
|
|
|
|
|
|
|
|
|
|
|
398 |
|
|
|
|
|
|
|
|
|
|
|
|
|
399 |
|
400 |
-
});})(jQuery);
|
7 |
// fix layout position
|
8 |
setTimeout(function () {
|
9 |
$('table.layout').length && $('table.layout td.left h2:first-child').css('margin-top', $('.wrap').offset().top - $('table.layout').offset().top);
|
10 |
+
}, 10);
|
|
|
11 |
|
12 |
// help icons
|
13 |
$('a.help').tipsy({
|
108 |
// choose file form: option selection dynamic
|
109 |
// options form: highlight options of selected post type
|
110 |
$('form.choose-file input[name="type"]').click(function() {
|
111 |
+
if ($(this).val() == 'upload' || $(this).val() == 'file' || $(this).val() == 'reimport' || $(this).val() == 'url') $('#large_import').slideDown(); else { $('#large_import').slideUp(); $('#large_import_toggle').removeAttr('checked'); $('#large_import_xpath').slideUp();}
|
112 |
var $container = $(this).parents('.file-type-container');
|
113 |
$('.file-type-container').not($container).removeClass('selected').find('.file-type-options').hide();
|
114 |
$container.addClass('selected').find('.file-type-options').show();
|
154 |
return false;
|
155 |
});
|
156 |
// options form: auto submit when `load options` checkbox is checked
|
157 |
+
$('input[name="load_options"]').click(function () {
|
158 |
if ($(this).is(':checked')) $(this).parents('form').submit();
|
159 |
});
|
160 |
// options form: auto submit when `reset options` checkbox is checked
|
198 |
if (action.init) {
|
199 |
this.data('initialized', true);
|
200 |
// add expander
|
201 |
+
this.find('.xml-expander').live('click', function () {
|
202 |
var method;
|
203 |
if ('-' == $(this).text()) {
|
204 |
$(this).text('+');
|
279 |
}
|
280 |
});
|
281 |
|
282 |
+
if ($('#content').length && window.tinymce != undefined) tinymce.dom.Event.add('wp-content-editor-container', 'click', function(e) {
|
283 |
if (dblclickbuf.selected)
|
284 |
{
|
285 |
tinyMCE.activeEditor.selection.setContent(dblclickbuf.value);
|
291 |
|
292 |
this.find('.xml-tag.opening > .xml-tag-name, .xml-attr-name').each(function () {
|
293 |
var $this = $(this);
|
294 |
+
var xpath = '.';
|
295 |
+
if ($this.is('.xml-attr-name'))
|
296 |
+
xpath = '{' + ($this.parents('.xml-element:first').attr('title').replace(/^\/[^\/]+\/?/, '') || '.') + '/@' + $this.html().trim() + '}';
|
297 |
+
else
|
298 |
+
xpath = '{' + ($this.parent().parent().attr('title').replace(/^\/[^\/]+\/?/, '') || '.') + '}';
|
299 |
|
300 |
$this.mouseover(function (e) {
|
301 |
$drag.val(xpath).offset({left: $this.offset().left - 2, top: $this.offset().top - 2}).width(_w = $this.width() + 4).height($this.height() + 4);
|
309 |
$('form.choose-elements').each(function () {
|
310 |
var $form = $(this);
|
311 |
$form.find('.xml').xml();
|
312 |
+
var $input = $form.find('input[name="xpath"]');
|
313 |
+
var $next_element = $form.find('#next_element');
|
314 |
+
var $prev_element = $form.find('#prev_element');
|
315 |
+
var $goto_element = $form.find('#goto_element');
|
316 |
+
var $get_default_xpath = $form.find('#get_default_xpath');
|
317 |
+
var $root_element = $form.find('#root_element');
|
318 |
+
|
319 |
+
var $xml = $('.xml');
|
320 |
+
$form.find('.xml-tag.opening').live('mousedown', function () {return false;}).live('dblclick', function () {
|
321 |
if ($form.hasClass('loading')) return; // do nothing if selecting operation is currently under way
|
322 |
$input.val($(this).parents('.xml-element').first().attr('title').replace(/\[\d+\]$/, '')).change();
|
323 |
});
|
324 |
var xpathChanged = function () {
|
325 |
+
if ($input.val() == $input.data('checkedValue')) return;
|
326 |
+
var xpath_elements = $input.val().split('[');
|
327 |
+
var xpath_parts = xpath_elements[0].split('/');
|
328 |
+
xpath_elements[0] = '';
|
329 |
+
$input.val('/' + xpath_parts[xpath_parts.length - 1] + ((xpath_elements.length) ? xpath_elements.join('[') : ''));
|
330 |
+
$form.addClass('loading');
|
331 |
$form.find('.xml-element.selected').removeClass('selected'); // clear current selection
|
332 |
// request server to return elements which correspond to xpath entered
|
333 |
$input.attr('readonly', true).unbind('change', xpathChanged).data('checkedValue', $input.val());
|
334 |
+
$xml.css({'visibility':'hidden'});
|
335 |
+
$xml.parents('fieldset:first').addClass('preload');
|
336 |
+
$('.ajax-console').load('admin.php?page=pmxi-admin-import&action=evaluate', {xpath: $input.val(), show_element: $goto_element.val(), root_element:$root_element.val()}, function () {
|
337 |
+
$input.attr('readonly', false).change(function(){$goto_element.val(1); xpathChanged();});
|
338 |
$form.removeClass('loading');
|
339 |
+
$xml.parents('fieldset:first').removeClass('preload');
|
340 |
});
|
341 |
};
|
342 |
+
$next_element.click(function(){
|
343 |
+
var show_element = Math.min((parseInt($goto_element.val()) + 1), parseInt($('.matches_count').html()));
|
344 |
+
$goto_element.val(show_element).html( show_element ); $input.data('checkedValue', ''); xpathChanged();
|
345 |
+
});
|
346 |
+
$prev_element.click(function(){
|
347 |
+
var show_element = Math.max((parseInt($goto_element.val()) - 1), 1);
|
348 |
+
$goto_element.val(show_element).html( show_element ); $input.data('checkedValue', ''); xpathChanged();
|
349 |
+
});
|
350 |
+
$goto_element.change(function(){
|
351 |
+
var show_element = Math.max(Math.min(parseInt($goto_element.val()), parseInt($('.matches_count').html())), 1);
|
352 |
+
$goto_element.val(show_element); $input.data('checkedValue', ''); xpathChanged();
|
353 |
+
});
|
354 |
+
$get_default_xpath.click(function(){$root_element.val($(this).attr('root')); $goto_element.val(1); $input.val($(this).attr('rel')); xpathChanged();});
|
355 |
+
$('.change_root_element').click(function(){
|
356 |
+
$root_element.val($(this).attr('rel')); $goto_element.val(1); $input.val('/' + $(this).attr('rel')); xpathChanged();
|
357 |
+
});
|
358 |
+
$input.change(function(){$goto_element.val(1); xpathChanged();}).change();
|
359 |
$input.keyup(function (e) {
|
360 |
if (13 == e.keyCode) $(this).change();
|
361 |
});
|
400 |
toleranceElement: '> div',
|
401 |
update: function () {
|
402 |
$(this).parents('td:first').find('.hierarhy-output').val(window.JSON.stringify($(this).nestedSortable('toArray', {startDepthCount: 0})));
|
403 |
+
if ($(this).parents('td:first').find('input:first').val() == '') $(this).parents('td:first').find('.hierarhy-output').val('');
|
404 |
}
|
405 |
});
|
406 |
|
407 |
$('.drag-element').find('input').live('blur', function(){
|
408 |
$(this).parents('td:first').find('.hierarhy-output').val(window.JSON.stringify($(this).parents('.sortable:first').nestedSortable('toArray', {startDepthCount: 0})));
|
409 |
+
if ($(this).parents('td:first').find('input:first').val() == '') $(this).parents('td:first').find('.hierarhy-output').val('');
|
410 |
+
});
|
411 |
+
|
412 |
+
$('.drag-element').find('input').live('change', function(){
|
413 |
+
$(this).parents('td:first').find('.hierarhy-output').val(window.JSON.stringify($(this).parents('.sortable:first').nestedSortable('toArray', {startDepthCount: 0})));
|
414 |
+
if ($(this).parents('td:first').find('input:first').val() == '') $(this).parents('td:first').find('.hierarhy-output').val('');
|
415 |
+
});
|
416 |
+
|
417 |
+
$('.drag-element').find('input').live('hover', function(){},function(){
|
418 |
+
$(this).parents('td:first').find('.hierarhy-output').val(window.JSON.stringify($(this).parents('.sortable:first').nestedSortable('toArray', {startDepthCount: 0})));
|
419 |
+
if ($(this).parents('td:first').find('input:first').val() == '') $(this).parents('td:first').find('.hierarhy-output').val('');
|
420 |
});
|
421 |
|
422 |
$('.sortable').find('.remove-ico').live('click', function(){
|
428 |
$(this).attr({'id':'item_'+ (i+1)});
|
429 |
});
|
430 |
parent_td.find('.hierarhy-output').val(window.JSON.stringify(parent_td.find('.sortable:first').nestedSortable('toArray', {startDepthCount: 0})));
|
431 |
+
if (parent_td.find('input:first').val() == '') parent_td.find('.hierarhy-output').val('');
|
432 |
});
|
433 |
|
434 |
$('.add-new-ico').click(function(){
|
435 |
var count = $(this).parents('tr:first').find('ol.sortable').find('li').length + 1;
|
436 |
+
$(this).parents('tr:first').find('ol.sortable').append('<li id="item_'+count+'"><div class="drag-element"><input type="checkbox" class="assign_post" checked="checked"/><input type="text" value="" class="widefat"></div><a class="icon-item remove-ico" href="javascript:void(0);"></a></li>');
|
437 |
+
$(this).parents('td:first').find('.hierarhy-output').val(window.JSON.stringify($(this).parents('.sortable:first').nestedSortable('toArray', {startDepthCount: 0})));
|
438 |
+
if ($(this).parents('td:first').find('input:first').val() == '') $(this).parents('td:first').find('.hierarhy-output').val('');
|
439 |
$('.widefat').bind('focus', insertxpath );
|
440 |
});
|
441 |
+
|
442 |
+
$('form.options').find('input[type=submit]').click(function(e){
|
443 |
+
e.preventDefault();
|
444 |
+
|
445 |
+
$('.hierarhy-output').each(function(){
|
446 |
+
$(this).val(window.JSON.stringify($(this).parents('td:first').find('.sortable:first').nestedSortable('toArray', {startDepthCount: 0})));
|
447 |
+
if ($(this).parents('td:first').find('input:first').val() == '') $(this).val('');
|
448 |
+
});
|
449 |
+
if ($(this).attr('name') == 'btn_save_only') $('.save_only').val('1');
|
450 |
+
$(this).parents('form:first').submit();
|
451 |
+
});
|
452 |
+
|
453 |
+
/* END Categories hierarchy */
|
454 |
+
|
455 |
+
// manage screen: cron url
|
456 |
+
$('.get_cron_url').each(function () {
|
457 |
+
var $form = $(this);
|
458 |
+
var $modal = $('<div></div>').dialog({
|
459 |
+
autoOpen: false,
|
460 |
+
modal: true,
|
461 |
+
title: 'Cron URLs',
|
462 |
+
width: 760,
|
463 |
+
maxHeight: 600,
|
464 |
+
open: function(event, ui) {
|
465 |
+
$(this).dialog('option', 'height', 'auto').css({'max-height': $(this).dialog('option', 'maxHeight') - $(this).prev().height() - 24, 'overflow-y': 'auto'});
|
466 |
+
}
|
467 |
+
});
|
468 |
+
$form.find('a').click(function () {
|
469 |
+
$modal.addClass('loading').empty().dialog('open').dialog('option', 'position', 'center');
|
470 |
+
$modal.removeClass('loading').html('<textarea style="width:100%; height:100%;">' + $form.find('a').attr('rel') + '</textarea>').dialog('option', 'position', 'center');
|
471 |
+
});
|
472 |
+
});
|
473 |
+
|
474 |
+
// chunk files upload
|
475 |
+
if ($('#plupload-ui').length)
|
476 |
+
{
|
477 |
+
$('#plupload-ui').show();
|
478 |
+
$('#html-upload-ui').hide();
|
479 |
+
|
480 |
+
wplupload = $('#select-files').wplupload({
|
481 |
+
runtimes : 'gears,browserplus,html5,flash,silverlight,html4',
|
482 |
+
url : 'admin.php?page=pmxi-admin-settings&action=upload',
|
483 |
+
container: 'plupload-ui',
|
484 |
+
browse_button : 'select-files',
|
485 |
+
file_data_name : 'async-upload',
|
486 |
+
flash_swf_url : plugin_url + '/static/js/plupload/plupload.flash.swf',
|
487 |
+
silverlight_xap_url : plugin_url + '/static/js/plupload/plupload.silverlight.xap',
|
488 |
+
|
489 |
+
multipart: false,
|
490 |
+
max_file_size: '500mb',
|
491 |
+
chunk_size: '1mb',
|
492 |
+
drop_element: 'plupload-ui'
|
493 |
+
});
|
494 |
+
}
|
495 |
+
|
496 |
+
/* END plupload scripts */
|
497 |
+
|
498 |
+
if ($('#large_import_toggle').is(':checked')) $('#large_import_xpath').slideToggle();
|
499 |
+
|
500 |
+
$('#large_import_toggle').click(function(){
|
501 |
+
$('#large_import_xpath').slideToggle();
|
502 |
+
});
|
503 |
+
|
504 |
+
// Step 4 - custom meta keys helper
|
505 |
+
|
506 |
+
if ($('#pmxi_tabs').length){
|
507 |
+
if ($('form.options').length){
|
508 |
+
if ($('#selected_post_type').val() != ''){
|
509 |
+
var post_type_founded = false;
|
510 |
+
$('input[name=custom_type]').each(function(i){
|
511 |
+
if ($(this).val() == $('#selected_post_type').val()) { $('#pmxi_tabs').tabs({ selected:i }).show(); post_type_founded = true; }
|
512 |
+
});
|
513 |
+
if ( ! post_type_founded){
|
514 |
+
$('#pmxi_tabs').tabs({ selected: ($('#selected_type').val() == 'post') ? 0 : 1 }).show();
|
515 |
+
}
|
516 |
+
}
|
517 |
+
else if ($('#selected_type').val() != ''){
|
518 |
+
$('#pmxi_tabs').tabs({ selected: ($('#selected_type').val() == 'post') ? 0 : 1 }).show();
|
519 |
+
}
|
520 |
+
}
|
521 |
+
else
|
522 |
+
$('#pmxi_tabs').tabs().show();
|
523 |
+
}
|
524 |
|
525 |
+
if ($('#upload_process').length){
|
526 |
+
$('#upload_process').progressbar({ value: (($('#progressbar').html() != '') ? 100 : 0) });
|
527 |
+
if ($('#progressbar').html() != '')
|
528 |
+
$('.submit-buttons').show();
|
529 |
+
}
|
530 |
|
531 |
+
$('#view_log').live('click', function(){
|
532 |
+
$('#import_finished').css({'visibility':'hidden'});
|
533 |
+
$('#logwrapper').slideToggle(100, function(){
|
534 |
+
$('#import_finished').css({'visibility':'visible'});
|
535 |
+
});
|
536 |
+
});
|
537 |
|
538 |
+
$(document).scroll(function() {
|
539 |
+
if ($(document).scrollTop() > 135)
|
540 |
+
$('.tag').css({'top':'30px'});
|
541 |
+
else
|
542 |
+
$('.tag').css({'top':''});
|
543 |
+
});
|
544 |
|
545 |
+
});})(jQuery);
|
static/js/jquery/css/redmond/images/animated-overlay.gif
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100_1.png
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-bg_flat_55_fbec88_40x100.png
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-bg_glass_85_dfeffc_1x400.png
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-bg_glass_95_fef1ec_1x400.png
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-icons_217bc0_256x240.png
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-icons_2e83ff_256x240.png
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-icons_469bdd_256x240.png
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-icons_6da8d5_256x240.png
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-icons_cd0a0a_256x240.png
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-icons_d8e7f3_256x240.png
ADDED
Binary file
|
static/js/jquery/css/redmond/images/ui-icons_f9bd01_256x240.png
ADDED
Binary file
|
static/js/jquery/css/redmond/jquery-ui.css
ADDED
@@ -0,0 +1,1177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*! jQuery UI - v1.10.0 - 2013-02-06
|
2 |
+
* http://jqueryui.com
|
3 |
+
* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
|
4 |
+
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande%2CLucida%20Sans%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=5px&bgColorHeader=5c9ccc&bgTextureHeader=gloss_wave&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=inset_hard&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDefault=glass&bgImgOpacityDefault=85&borderColorDefault=c5dbec&fcDefault=2e6e9e&iconColorDefault=6da8d5&bgColorHover=d0e5f5&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=79b7e7&fcHover=1d5987&iconColorHover=217bc0&bgColorActive=f5f8f9&bgTextureActive=inset_hard&bgImgOpacityActive=100&borderColorActive=79b7e7&fcActive=e17009&iconColorActive=f9bd01&bgColorHighlight=fbec88&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=fad42e&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
|
5 |
+
* Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */
|
6 |
+
|
7 |
+
/* Layout helpers
|
8 |
+
----------------------------------*/
|
9 |
+
.ui-helper-hidden {
|
10 |
+
display: none;
|
11 |
+
}
|
12 |
+
.ui-helper-hidden-accessible {
|
13 |
+
border: 0;
|
14 |
+
clip: rect(0 0 0 0);
|
15 |
+
height: 1px;
|
16 |
+
margin: -1px;
|
17 |
+
overflow: hidden;
|
18 |
+
padding: 0;
|
19 |
+
position: absolute;
|
20 |
+
width: 1px;
|
21 |
+
}
|
22 |
+
.ui-helper-reset {
|
23 |
+
margin: 0;
|
24 |
+
padding: 0;
|
25 |
+
border: 0;
|
26 |
+
outline: 0;
|
27 |
+
line-height: 1.3;
|
28 |
+
text-decoration: none;
|
29 |
+
font-size: 100%;
|
30 |
+
list-style: none;
|
31 |
+
}
|
32 |
+
.ui-helper-clearfix:before,
|
33 |
+
.ui-helper-clearfix:after {
|
34 |
+
content: "";
|
35 |
+
display: table;
|
36 |
+
}
|
37 |
+
.ui-helper-clearfix:after {
|
38 |
+
clear: both;
|
39 |
+
}
|
40 |
+
.ui-helper-clearfix {
|
41 |
+
min-height: 0; /* support: IE7 */
|
42 |
+
}
|
43 |
+
.ui-helper-zfix {
|
44 |
+
width: 100%;
|
45 |
+
height: 100%;
|
46 |
+
top: 0;
|
47 |
+
left: 0;
|
48 |
+
position: absolute;
|
49 |
+
opacity: 0;
|
50 |
+
filter:Alpha(Opacity=0);
|
51 |
+
}
|
52 |
+
|
53 |
+
.ui-front {
|
54 |
+
z-index: 100;
|
55 |
+
}
|
56 |
+
|
57 |
+
|
58 |
+
/* Interaction Cues
|
59 |
+
----------------------------------*/
|
60 |
+
.ui-state-disabled {
|
61 |
+
cursor: default !important;
|
62 |
+
}
|
63 |
+
|
64 |
+
|
65 |
+
/* Icons
|
66 |
+
----------------------------------*/
|
67 |
+
|
68 |
+
/* states and images */
|
69 |
+
.ui-icon {
|
70 |
+
display: block;
|
71 |
+
text-indent: -99999px;
|
72 |
+
overflow: hidden;
|
73 |
+
background-repeat: no-repeat;
|
74 |
+
}
|
75 |
+
|
76 |
+
|
77 |
+
/* Misc visuals
|
78 |
+
----------------------------------*/
|
79 |
+
|
80 |
+
/* Overlays */
|
81 |
+
.ui-widget-overlay {
|
82 |
+
position: fixed;
|
83 |
+
top: 0;
|
84 |
+
left: 0;
|
85 |
+
width: 100%;
|
86 |
+
height: 100%;
|
87 |
+
}
|
88 |
+
.ui-resizable {
|
89 |
+
position: relative;
|
90 |
+
}
|
91 |
+
.ui-resizable-handle {
|
92 |
+
position: absolute;
|
93 |
+
font-size: 0.1px;
|
94 |
+
display: block;
|
95 |
+
}
|
96 |
+
.ui-resizable-disabled .ui-resizable-handle,
|
97 |
+
.ui-resizable-autohide .ui-resizable-handle {
|
98 |
+
display: none;
|
99 |
+
}
|
100 |
+
.ui-resizable-n {
|
101 |
+
cursor: n-resize;
|
102 |
+
height: 7px;
|
103 |
+
width: 100%;
|
104 |
+
top: -5px;
|
105 |
+
left: 0;
|
106 |
+
}
|
107 |
+
.ui-resizable-s {
|
108 |
+
cursor: s-resize;
|
109 |
+
height: 7px;
|
110 |
+
width: 100%;
|
111 |
+
bottom: -5px;
|
112 |
+
left: 0;
|
113 |
+
}
|
114 |
+
.ui-resizable-e {
|
115 |
+
cursor: e-resize;
|
116 |
+
width: 7px;
|
117 |
+
right: -5px;
|
118 |
+
top: 0;
|
119 |
+
height: 100%;
|
120 |
+
}
|
121 |
+
.ui-resizable-w {
|
122 |
+
cursor: w-resize;
|
123 |
+
width: 7px;
|
124 |
+
left: -5px;
|
125 |
+
top: 0;
|
126 |
+
height: 100%;
|
127 |
+
}
|
128 |
+
.ui-resizable-se {
|
129 |
+
cursor: se-resize;
|
130 |
+
width: 12px;
|
131 |
+
height: 12px;
|
132 |
+
right: 1px;
|
133 |
+
bottom: 1px;
|
134 |
+
}
|
135 |
+
.ui-resizable-sw {
|
136 |
+
cursor: sw-resize;
|
137 |
+
width: 9px;
|
138 |
+
height: 9px;
|
139 |
+
left: -5px;
|
140 |
+
bottom: -5px;
|
141 |
+
}
|
142 |
+
.ui-resizable-nw {
|
143 |
+
cursor: nw-resize;
|
144 |
+
width: 9px;
|
145 |
+
height: 9px;
|
146 |
+
left: -5px;
|
147 |
+
top: -5px;
|
148 |
+
}
|
149 |
+
.ui-resizable-ne {
|
150 |
+
cursor: ne-resize;
|
151 |
+
width: 9px;
|
152 |
+
height: 9px;
|
153 |
+
right: -5px;
|
154 |
+
top: -5px;
|
155 |
+
}
|
156 |
+
.ui-selectable-helper {
|
157 |
+
position: absolute;
|
158 |
+
z-index: 100;
|
159 |
+
border: 1px dotted black;
|
160 |
+
}
|
161 |
+
.ui-accordion .ui-accordion-header {
|
162 |
+
display: block;
|
163 |
+
cursor: pointer;
|
164 |
+
position: relative;
|
165 |
+
margin-top: 2px;
|
166 |
+
padding: .5em .5em .5em .7em;
|
167 |
+
min-height: 0; /* support: IE7 */
|
168 |
+
}
|
169 |
+
.ui-accordion .ui-accordion-icons {
|
170 |
+
padding-left: 2.2em;
|
171 |
+
}
|
172 |
+
.ui-accordion .ui-accordion-noicons {
|
173 |
+
padding-left: .7em;
|
174 |
+
}
|
175 |
+
.ui-accordion .ui-accordion-icons .ui-accordion-icons {
|
176 |
+
padding-left: 2.2em;
|
177 |
+
}
|
178 |
+
.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
|
179 |
+
position: absolute;
|
180 |
+
left: .5em;
|
181 |
+
top: 50%;
|
182 |
+
margin-top: -8px;
|
183 |
+
}
|
184 |
+
.ui-accordion .ui-accordion-content {
|
185 |
+
padding: 1em 2.2em;
|
186 |
+
border-top: 0;
|
187 |
+
overflow: auto;
|
188 |
+
}
|
189 |
+
.ui-autocomplete {
|
190 |
+
position: absolute;
|
191 |
+
top: 0;
|
192 |
+
left: 0;
|
193 |
+
cursor: default;
|
194 |
+
}
|
195 |
+
.ui-button {
|
196 |
+
display: inline-block;
|
197 |
+
position: relative;
|
198 |
+
padding: 0;
|
199 |
+
line-height: normal;
|
200 |
+
margin-right: .1em;
|
201 |
+
cursor: pointer;
|
202 |
+
vertical-align: middle;
|
203 |
+
text-align: center;
|
204 |
+
overflow: visible; /* removes extra width in IE */
|
205 |
+
}
|
206 |
+
.ui-button,
|
207 |
+
.ui-button:visited,
|
208 |
+
.ui-button:hover,
|
209 |
+
.ui-button:active,
|
210 |
+
.large_button:hover {
|
211 |
+
background: url("images/ui-bg_glass_75_d0e5f5_1x400.png") repeat-x scroll 50% 50% #D0E5F5;
|
212 |
+
border: 1px solid #79B7E7;
|
213 |
+
color: #1D5987;
|
214 |
+
font-weight: bold;
|
215 |
+
}
|
216 |
+
/* to make room for the icon, a width needs to be set here */
|
217 |
+
.ui-button-icon-only {
|
218 |
+
width: 2.2em;
|
219 |
+
}
|
220 |
+
/* button elements seem to need a little more width */
|
221 |
+
button.ui-button-icon-only {
|
222 |
+
width: 2.4em;
|
223 |
+
}
|
224 |
+
.ui-button-icons-only {
|
225 |
+
width: 3.4em;
|
226 |
+
}
|
227 |
+
button.ui-button-icons-only {
|
228 |
+
width: 3.7em;
|
229 |
+
}
|
230 |
+
|
231 |
+
/* button text element */
|
232 |
+
.ui-button .ui-button-text {
|
233 |
+
display: block;
|
234 |
+
line-height: normal;
|
235 |
+
}
|
236 |
+
.ui-button-text-only .ui-button-text {
|
237 |
+
padding: .4em 1em;
|
238 |
+
}
|
239 |
+
.ui-button-icon-only .ui-button-text,
|
240 |
+
.ui-button-icons-only .ui-button-text {
|
241 |
+
padding: .4em;
|
242 |
+
text-indent: -9999999px;
|
243 |
+
}
|
244 |
+
.ui-button-text-icon-primary .ui-button-text,
|
245 |
+
.ui-button-text-icons .ui-button-text {
|
246 |
+
padding: .4em 1em .4em 2.1em;
|
247 |
+
}
|
248 |
+
.ui-button-text-icon-secondary .ui-button-text,
|
249 |
+
.ui-button-text-icons .ui-button-text {
|
250 |
+
padding: .4em 2.1em .4em 1em;
|
251 |
+
}
|
252 |
+
.ui-button-text-icons .ui-button-text {
|
253 |
+
padding-left: 2.1em;
|
254 |
+
padding-right: 2.1em;
|
255 |
+
}
|
256 |
+
/* no icon support for input elements, provide padding by default */
|
257 |
+
input.ui-button {
|
258 |
+
padding: .4em 1em;
|
259 |
+
}
|
260 |
+
|
261 |
+
/* button icon element(s) */
|
262 |
+
.ui-button-icon-only .ui-icon,
|
263 |
+
.ui-button-text-icon-primary .ui-icon,
|
264 |
+
.ui-button-text-icon-secondary .ui-icon,
|
265 |
+
.ui-button-text-icons .ui-icon,
|
266 |
+
.ui-button-icons-only .ui-icon {
|
267 |
+
position: absolute;
|
268 |
+
top: 50%;
|
269 |
+
margin-top: -8px;
|
270 |
+
}
|
271 |
+
.ui-button-icon-only .ui-icon {
|
272 |
+
left: 50%;
|
273 |
+
margin-left: -8px;
|
274 |
+
}
|
275 |
+
.ui-button-text-icon-primary .ui-button-icon-primary,
|
276 |
+
.ui-button-text-icons .ui-button-icon-primary,
|
277 |
+
.ui-button-icons-only .ui-button-icon-primary {
|
278 |
+
left: .5em;
|
279 |
+
}
|
280 |
+
.ui-button-text-icon-secondary .ui-button-icon-secondary,
|
281 |
+
.ui-button-text-icons .ui-button-icon-secondary,
|
282 |
+
.ui-button-icons-only .ui-button-icon-secondary {
|
283 |
+
right: .5em;
|
284 |
+
}
|
285 |
+
|
286 |
+
/* button sets */
|
287 |
+
.ui-buttonset {
|
288 |
+
margin-right: 7px;
|
289 |
+
}
|
290 |
+
.ui-buttonset .ui-button {
|
291 |
+
margin-left: 0;
|
292 |
+
margin-right: -.3em;
|
293 |
+
}
|
294 |
+
|
295 |
+
/* workarounds */
|
296 |
+
/* reset extra padding in Firefox, see h5bp.com/l */
|
297 |
+
input.ui-button::-moz-focus-inner,
|
298 |
+
button.ui-button::-moz-focus-inner {
|
299 |
+
border: 0;
|
300 |
+
padding: 0;
|
301 |
+
}
|
302 |
+
.ui-datepicker {
|
303 |
+
width: 17em;
|
304 |
+
padding: .2em .2em 0;
|
305 |
+
display: none;
|
306 |
+
}
|
307 |
+
.ui-datepicker .ui-datepicker-header {
|
308 |
+
position: relative;
|
309 |
+
padding: .2em 0;
|
310 |
+
}
|
311 |
+
.ui-datepicker .ui-datepicker-prev,
|
312 |
+
.ui-datepicker .ui-datepicker-next {
|
313 |
+
position: absolute;
|
314 |
+
top: 2px;
|
315 |
+
width: 1.8em;
|
316 |
+
height: 1.8em;
|
317 |
+
}
|
318 |
+
.ui-datepicker .ui-datepicker-prev-hover,
|
319 |
+
.ui-datepicker .ui-datepicker-next-hover {
|
320 |
+
top: 1px;
|
321 |
+
}
|
322 |
+
.ui-datepicker .ui-datepicker-prev {
|
323 |
+
left: 2px;
|
324 |
+
}
|
325 |
+
.ui-datepicker .ui-datepicker-next {
|
326 |
+
right: 2px;
|
327 |
+
}
|
328 |
+
.ui-datepicker .ui-datepicker-prev-hover {
|
329 |
+
left: 1px;
|
330 |
+
}
|
331 |
+
.ui-datepicker .ui-datepicker-next-hover {
|
332 |
+
right: 1px;
|
333 |
+
}
|
334 |
+
.ui-datepicker .ui-datepicker-prev span,
|
335 |
+
.ui-datepicker .ui-datepicker-next span {
|
336 |
+
display: block;
|
337 |
+
position: absolute;
|
338 |
+
left: 50%;
|
339 |
+
margin-left: -8px;
|
340 |
+
top: 50%;
|
341 |
+
margin-top: -8px;
|
342 |
+
}
|
343 |
+
.ui-datepicker .ui-datepicker-title {
|
344 |
+
margin: 0 2.3em;
|
345 |
+
line-height: 1.8em;
|
346 |
+
text-align: center;
|
347 |
+
}
|
348 |
+
.ui-datepicker .ui-datepicker-title select {
|
349 |
+
font-size: 1em;
|
350 |
+
margin: 1px 0;
|
351 |
+
}
|
352 |
+
.ui-datepicker select.ui-datepicker-month-year {
|
353 |
+
width: 100%;
|
354 |
+
}
|
355 |
+
.ui-datepicker select.ui-datepicker-month,
|
356 |
+
.ui-datepicker select.ui-datepicker-year {
|
357 |
+
width: 49%;
|
358 |
+
}
|
359 |
+
.ui-datepicker table {
|
360 |
+
width: 100%;
|
361 |
+
font-size: .9em;
|
362 |
+
border-collapse: collapse;
|
363 |
+
margin: 0 0 .4em;
|
364 |
+
}
|
365 |
+
.ui-datepicker th {
|
366 |
+
padding: .7em .3em;
|
367 |
+
text-align: center;
|
368 |
+
font-weight: bold;
|
369 |
+
border: 0;
|
370 |
+
}
|
371 |
+
.ui-datepicker td {
|
372 |
+
border: 0;
|
373 |
+
padding: 1px;
|
374 |
+
}
|
375 |
+
.ui-datepicker td span,
|
376 |
+
.ui-datepicker td a {
|
377 |
+
display: block;
|
378 |
+
padding: .2em;
|
379 |
+
text-align: right;
|
380 |
+
text-decoration: none;
|
381 |
+
}
|
382 |
+
.ui-datepicker .ui-datepicker-buttonpane {
|
383 |
+
background-image: none;
|
384 |
+
margin: .7em 0 0 0;
|
385 |
+
padding: 0 .2em;
|
386 |
+
border-left: 0;
|
387 |
+
border-right: 0;
|
388 |
+
border-bottom: 0;
|
389 |
+
}
|
390 |
+
.ui-datepicker .ui-datepicker-buttonpane button {
|
391 |
+
float: right;
|
392 |
+
margin: .5em .2em .4em;
|
393 |
+
cursor: pointer;
|
394 |
+
padding: .2em .6em .3em .6em;
|
395 |
+
width: auto;
|
396 |
+
overflow: visible;
|
397 |
+
}
|
398 |
+
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
|
399 |
+
float: left;
|
400 |
+
}
|
401 |
+
|
402 |
+
/* with multiple calendars */
|
403 |
+
.ui-datepicker.ui-datepicker-multi {
|
404 |
+
width: auto;
|
405 |
+
}
|
406 |
+
.ui-datepicker-multi .ui-datepicker-group {
|
407 |
+
float: left;
|
408 |
+
}
|
409 |
+
.ui-datepicker-multi .ui-datepicker-group table {
|
410 |
+
width: 95%;
|
411 |
+
margin: 0 auto .4em;
|
412 |
+
}
|
413 |
+
.ui-datepicker-multi-2 .ui-datepicker-group {
|
414 |
+
width: 50%;
|
415 |
+
}
|
416 |
+
.ui-datepicker-multi-3 .ui-datepicker-group {
|
417 |
+
width: 33.3%;
|
418 |
+
}
|
419 |
+
.ui-datepicker-multi-4 .ui-datepicker-group {
|
420 |
+
width: 25%;
|
421 |
+
}
|
422 |
+
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
|
423 |
+
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
|
424 |
+
border-left-width: 0;
|
425 |
+
}
|
426 |
+
.ui-datepicker-multi .ui-datepicker-buttonpane {
|
427 |
+
clear: left;
|
428 |
+
}
|
429 |
+
.ui-datepicker-row-break {
|
430 |
+
clear: both;
|
431 |
+
width: 100%;
|
432 |
+
font-size: 0;
|
433 |
+
}
|
434 |
+
|
435 |
+
/* RTL support */
|
436 |
+
.ui-datepicker-rtl {
|
437 |
+
direction: rtl;
|
438 |
+
}
|
439 |
+
.ui-datepicker-rtl .ui-datepicker-prev {
|
440 |
+
right: 2px;
|
441 |
+
left: auto;
|
442 |
+
}
|
443 |
+
.ui-datepicker-rtl .ui-datepicker-next {
|
444 |
+
left: 2px;
|
445 |
+
right: auto;
|
446 |
+
}
|
447 |
+
.ui-datepicker-rtl .ui-datepicker-prev:hover {
|
448 |
+
right: 1px;
|
449 |
+
left: auto;
|
450 |
+
}
|
451 |
+
.ui-datepicker-rtl .ui-datepicker-next:hover {
|
452 |
+
left: 1px;
|
453 |
+
right: auto;
|
454 |
+
}
|
455 |
+
.ui-datepicker-rtl .ui-datepicker-buttonpane {
|
456 |
+
clear: right;
|
457 |
+
}
|
458 |
+
.ui-datepicker-rtl .ui-datepicker-buttonpane button {
|
459 |
+
float: left;
|
460 |
+
}
|
461 |
+
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
|
462 |
+
.ui-datepicker-rtl .ui-datepicker-group {
|
463 |
+
float: right;
|
464 |
+
}
|
465 |
+
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
|
466 |
+
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
|
467 |
+
border-right-width: 0;
|
468 |
+
border-left-width: 1px;
|
469 |
+
}
|
470 |
+
.ui-dialog {
|
471 |
+
position: absolute;
|
472 |
+
top: 0;
|
473 |
+
left: 0;
|
474 |
+
padding: .2em;
|
475 |
+
outline: 0;
|
476 |
+
}
|
477 |
+
.ui-dialog .ui-dialog-titlebar {
|
478 |
+
padding: .4em 1em;
|
479 |
+
position: relative;
|
480 |
+
}
|
481 |
+
.ui-dialog .ui-dialog-title {
|
482 |
+
float: left;
|
483 |
+
margin: .1em 0;
|
484 |
+
white-space: nowrap;
|
485 |
+
width: 90%;
|
486 |
+
overflow: hidden;
|
487 |
+
text-overflow: ellipsis;
|
488 |
+
}
|
489 |
+
.ui-dialog .ui-dialog-titlebar-close {
|
490 |
+
position: absolute;
|
491 |
+
right: .3em;
|
492 |
+
top: 50%;
|
493 |
+
width: 21px;
|
494 |
+
margin: -10px 0 0 0;
|
495 |
+
padding: 1px;
|
496 |
+
height: 20px;
|
497 |
+
}
|
498 |
+
.ui-dialog .ui-dialog-content {
|
499 |
+
position: relative;
|
500 |
+
border: 0;
|
501 |
+
padding: .5em 1em;
|
502 |
+
background: none;
|
503 |
+
overflow: auto;
|
504 |
+
}
|
505 |
+
.ui-dialog .ui-dialog-buttonpane {
|
506 |
+
text-align: left;
|
507 |
+
border-width: 1px 0 0 0;
|
508 |
+
background-image: none;
|
509 |
+
margin-top: .5em;
|
510 |
+
padding: .3em 1em .5em .4em;
|
511 |
+
}
|
512 |
+
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
|
513 |
+
float: right;
|
514 |
+
}
|
515 |
+
.ui-dialog .ui-dialog-buttonpane button {
|
516 |
+
margin: .5em .4em .5em 0;
|
517 |
+
cursor: pointer;
|
518 |
+
}
|
519 |
+
.ui-dialog .ui-resizable-se {
|
520 |
+
width: 12px;
|
521 |
+
height: 12px;
|
522 |
+
right: -5px;
|
523 |
+
bottom: -5px;
|
524 |
+
background-position: 16px 16px;
|
525 |
+
}
|
526 |
+
.ui-draggable .ui-dialog-titlebar {
|
527 |
+
cursor: move;
|
528 |
+
}
|
529 |
+
.ui-menu {
|
530 |
+
list-style: none;
|
531 |
+
padding: 2px;
|
532 |
+
margin: 0;
|
533 |
+
display: block;
|
534 |
+
outline: none;
|
535 |
+
}
|
536 |
+
.ui-menu .ui-menu {
|
537 |
+
margin-top: -3px;
|
538 |
+
position: absolute;
|
539 |
+
}
|
540 |
+
.ui-menu .ui-menu-item {
|
541 |
+
margin: 0;
|
542 |
+
padding: 0;
|
543 |
+
width: 100%;
|
544 |
+
}
|
545 |
+
.ui-menu .ui-menu-divider {
|
546 |
+
margin: 5px -2px 5px -2px;
|
547 |
+
height: 0;
|
548 |
+
font-size: 0;
|
549 |
+
line-height: 0;
|
550 |
+
border-width: 1px 0 0 0;
|
551 |
+
}
|
552 |
+
.ui-menu .ui-menu-item a {
|
553 |
+
text-decoration: none;
|
554 |
+
display: block;
|
555 |
+
padding: 2px .4em;
|
556 |
+
line-height: 1.5;
|
557 |
+
min-height: 0; /* support: IE7 */
|
558 |
+
font-weight: normal;
|
559 |
+
}
|
560 |
+
.ui-menu .ui-menu-item a.ui-state-focus,
|
561 |
+
.ui-menu .ui-menu-item a.ui-state-active {
|
562 |
+
font-weight: normal;
|
563 |
+
margin: -1px;
|
564 |
+
}
|
565 |
+
|
566 |
+
.ui-menu .ui-state-disabled {
|
567 |
+
font-weight: normal;
|
568 |
+
margin: .4em 0 .2em;
|
569 |
+
line-height: 1.5;
|
570 |
+
}
|
571 |
+
.ui-menu .ui-state-disabled a {
|
572 |
+
cursor: default;
|
573 |
+
}
|
574 |
+
|
575 |
+
/* icon support */
|
576 |
+
.ui-menu-icons {
|
577 |
+
position: relative;
|
578 |
+
}
|
579 |
+
.ui-menu-icons .ui-menu-item a {
|
580 |
+
position: relative;
|
581 |
+
padding-left: 2em;
|
582 |
+
}
|
583 |
+
|
584 |
+
/* left-aligned */
|
585 |
+
.ui-menu .ui-icon {
|
586 |
+
position: absolute;
|
587 |
+
top: .2em;
|
588 |
+
left: .2em;
|
589 |
+
}
|
590 |
+
|
591 |
+
/* right-aligned */
|
592 |
+
.ui-menu .ui-menu-icon {
|
593 |
+
position: static;
|
594 |
+
float: right;
|
595 |
+
}
|
596 |
+
.ui-progressbar {
|
597 |
+
height: 2em;
|
598 |
+
text-align: left;
|
599 |
+
overflow: hidden;
|
600 |
+
}
|
601 |
+
.ui-progressbar .ui-progressbar-value {
|
602 |
+
margin: -1px;
|
603 |
+
height: 100%;
|
604 |
+
}
|
605 |
+
.ui-progressbar .ui-progressbar-overlay {
|
606 |
+
background: url("images/animated-overlay.gif");
|
607 |
+
height: 100%;
|
608 |
+
filter: alpha(opacity=25);
|
609 |
+
opacity: 0.25;
|
610 |
+
}
|
611 |
+
.ui-progressbar-indeterminate .ui-progressbar-value {
|
612 |
+
background-image: none;
|
613 |
+
}
|
614 |
+
.ui-slider {
|
615 |
+
position: relative;
|
616 |
+
text-align: left;
|
617 |
+
}
|
618 |
+
.ui-slider .ui-slider-handle {
|
619 |
+
position: absolute;
|
620 |
+
z-index: 2;
|
621 |
+
width: 1.2em;
|
622 |
+
height: 1.2em;
|
623 |
+
cursor: default;
|
624 |
+
}
|
625 |
+
.ui-slider .ui-slider-range {
|
626 |
+
position: absolute;
|
627 |
+
z-index: 1;
|
628 |
+
font-size: .7em;
|
629 |
+
display: block;
|
630 |
+
border: 0;
|
631 |
+
background-position: 0 0;
|
632 |
+
}
|
633 |
+
|
634 |
+
/* For IE8 - See #6727 */
|
635 |
+
.ui-slider.ui-state-disabled .ui-slider-handle,
|
636 |
+
.ui-slider.ui-state-disabled .ui-slider-range {
|
637 |
+
filter: inherit;
|
638 |
+
}
|
639 |
+
|
640 |
+
.ui-slider-horizontal {
|
641 |
+
height: .8em;
|
642 |
+
}
|
643 |
+
.ui-slider-horizontal .ui-slider-handle {
|
644 |
+
top: -.3em;
|
645 |
+
margin-left: -.6em;
|
646 |
+
}
|
647 |
+
.ui-slider-horizontal .ui-slider-range {
|
648 |
+
top: 0;
|
649 |
+
height: 100%;
|
650 |
+
}
|
651 |
+
.ui-slider-horizontal .ui-slider-range-min {
|
652 |
+
left: 0;
|
653 |
+
}
|
654 |
+
.ui-slider-horizontal .ui-slider-range-max {
|
655 |
+
right: 0;
|
656 |
+
}
|
657 |
+
|
658 |
+
.ui-slider-vertical {
|
659 |
+
width: .8em;
|
660 |
+
height: 100px;
|
661 |
+
}
|
662 |
+
.ui-slider-vertical .ui-slider-handle {
|
663 |
+
left: -.3em;
|
664 |
+
margin-left: 0;
|
665 |
+
margin-bottom: -.6em;
|
666 |
+
}
|
667 |
+
.ui-slider-vertical .ui-slider-range {
|
668 |
+
left: 0;
|
669 |
+
width: 100%;
|
670 |
+
}
|
671 |
+
.ui-slider-vertical .ui-slider-range-min {
|
672 |
+
bottom: 0;
|
673 |
+
}
|
674 |
+
.ui-slider-vertical .ui-slider-range-max {
|
675 |
+
top: 0;
|
676 |
+
}
|
677 |
+
.ui-spinner {
|
678 |
+
position: relative;
|
679 |
+
display: inline-block;
|
680 |
+
overflow: hidden;
|
681 |
+
padding: 0;
|
682 |
+
vertical-align: middle;
|
683 |
+
}
|
684 |
+
.ui-spinner-input {
|
685 |
+
border: none;
|
686 |
+
background: none;
|
687 |
+
color: inherit;
|
688 |
+
padding: 0;
|
689 |
+
margin: .2em 0;
|
690 |
+
vertical-align: middle;
|
691 |
+
margin-left: .4em;
|
692 |
+
margin-right: 22px;
|
693 |
+
}
|
694 |
+
.ui-spinner-button {
|
695 |
+
width: 16px;
|
696 |
+
height: 50%;
|
697 |
+
font-size: .5em;
|
698 |
+
padding: 0;
|
699 |
+
margin: 0;
|
700 |
+
text-align: center;
|
701 |
+
position: absolute;
|
702 |
+
cursor: default;
|
703 |
+
display: block;
|
704 |
+
overflow: hidden;
|
705 |
+
right: 0;
|
706 |
+
}
|
707 |
+
/* more specificity required here to overide default borders */
|
708 |
+
.ui-spinner a.ui-spinner-button {
|
709 |
+
border-top: none;
|
710 |
+
border-bottom: none;
|
711 |
+
border-right: none;
|
712 |
+
}
|
713 |
+
/* vertical centre icon */
|
714 |
+
.ui-spinner .ui-icon {
|
715 |
+
position: absolute;
|
716 |
+
margin-top: -8px;
|
717 |
+
top: 50%;
|
718 |
+
left: 0;
|
719 |
+
}
|
720 |
+
.ui-spinner-up {
|
721 |
+
top: 0;
|
722 |
+
}
|
723 |
+
.ui-spinner-down {
|
724 |
+
bottom: 0;
|
725 |
+
}
|
726 |
+
|
727 |
+
/* TR overrides */
|
728 |
+
.ui-spinner .ui-icon-triangle-1-s {
|
729 |
+
/* need to fix icons sprite */
|
730 |
+
background-position: -65px -16px;
|
731 |
+
}
|
732 |
+
.ui-tabs {
|
733 |
+
position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
|
734 |
+
padding: .2em;
|
735 |
+
}
|
736 |
+
.ui-tabs .ui-tabs-nav {
|
737 |
+
margin: 0;
|
738 |
+
padding: .2em .2em 0;
|
739 |
+
}
|
740 |
+
.ui-tabs .ui-tabs-nav li {
|
741 |
+
list-style: none;
|
742 |
+
float: left;
|
743 |
+
position: relative;
|
744 |
+
top: 0;
|
745 |
+
margin: 1px .2em 0 0;
|
746 |
+
border-bottom: 0;
|
747 |
+
padding: 0;
|
748 |
+
white-space: nowrap;
|
749 |
+
}
|
750 |
+
.ui-tabs .ui-tabs-nav li a {
|
751 |
+
float: left;
|
752 |
+
padding: .5em 1em;
|
753 |
+
text-decoration: none;
|
754 |
+
}
|
755 |
+
.ui-tabs .ui-tabs-nav li.ui-tabs-active {
|
756 |
+
margin-bottom: -1px;
|
757 |
+
padding-bottom: 1px;
|
758 |
+
}
|
759 |
+
.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
|
760 |
+
.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
|
761 |
+
.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
|
762 |
+
cursor: text;
|
763 |
+
}
|
764 |
+
.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
|
765 |
+
.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
|
766 |
+
cursor: pointer;
|
767 |
+
}
|
768 |
+
.ui-tabs .ui-tabs-panel {
|
769 |
+
display: block;
|
770 |
+
border-width: 0;
|
771 |
+
padding: 1em 1.4em;
|
772 |
+
background: none;
|
773 |
+
}
|
774 |
+
.ui-tooltip {
|
775 |
+
padding: 8px;
|
776 |
+
position: absolute;
|
777 |
+
z-index: 9999;
|
778 |
+
max-width: 300px;
|
779 |
+
-webkit-box-shadow: 0 0 5px #aaa;
|
780 |
+
box-shadow: 0 0 5px #aaa;
|
781 |
+
}
|
782 |
+
body .ui-tooltip {
|
783 |
+
border-width: 2px;
|
784 |
+
}
|
785 |
+
|
786 |
+
/* Component containers
|
787 |
+
----------------------------------*/
|
788 |
+
.ui-widget {
|
789 |
+
font-family: Lucida Grande,Lucida Sans,Arial,sans-serif;
|
790 |
+
font-size: 1.1em;
|
791 |
+
}
|
792 |
+
.ui-widget .ui-widget {
|
793 |
+
font-size: 1em;
|
794 |
+
}
|
795 |
+
.ui-widget input,
|
796 |
+
.ui-widget select,
|
797 |
+
.ui-widget textarea,
|
798 |
+
.ui-widget button {
|
799 |
+
font-family: Lucida Grande,Lucida Sans,Arial,sans-serif;
|
800 |
+
font-size: 1em;
|
801 |
+
}
|
802 |
+
.ui-widget-content {
|
803 |
+
border: 1px solid #a6c9e2;
|
804 |
+
background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x;
|
805 |
+
color: #222222;
|
806 |
+
}
|
807 |
+
.ui-widget-content a {
|
808 |
+
color: #222222;
|
809 |
+
}
|
810 |
+
.ui-widget-header {
|
811 |
+
border: 1px solid #4297d7;
|
812 |
+
background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x;
|
813 |
+
color: #ffffff;
|
814 |
+
font-weight: bold;
|
815 |
+
}
|
816 |
+
.ui-widget-header a {
|
817 |
+
color: #ffffff;
|
818 |
+
}
|
819 |
+
|
820 |
+
/* Interaction states
|
821 |
+
----------------------------------*/
|
822 |
+
.ui-state-default,
|
823 |
+
.ui-widget-content .ui-state-default,
|
824 |
+
.ui-widget-header .ui-state-default {
|
825 |
+
border: 1px solid #c5dbec;
|
826 |
+
background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x;
|
827 |
+
font-weight: bold;
|
828 |
+
color: #2e6e9e;
|
829 |
+
}
|
830 |
+
.ui-state-default a,
|
831 |
+
.ui-state-default a:link,
|
832 |
+
.ui-state-default a:visited {
|
833 |
+
color: #2e6e9e;
|
834 |
+
text-decoration: none;
|
835 |
+
}
|
836 |
+
.ui-state-hover,
|
837 |
+
.ui-widget-content .ui-state-hover,
|
838 |
+
.ui-widget-header .ui-state-hover,
|
839 |
+
.ui-state-focus,
|
840 |
+
.ui-widget-content .ui-state-focus,
|
841 |
+
.ui-widget-header .ui-state-focus {
|
842 |
+
border: 1px solid #79b7e7;
|
843 |
+
background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x;
|
844 |
+
font-weight: bold;
|
845 |
+
color: #1d5987;
|
846 |
+
}
|
847 |
+
.ui-state-hover a,
|
848 |
+
.ui-state-hover a:hover,
|
849 |
+
.ui-state-hover a:link,
|
850 |
+
.ui-state-hover a:visited {
|
851 |
+
color: #1d5987;
|
852 |
+
text-decoration: none;
|
853 |
+
}
|
854 |
+
.ui-state-active,
|
855 |
+
.ui-widget-content .ui-state-active,
|
856 |
+
.ui-widget-header .ui-state-active {
|
857 |
+
border: 1px solid #79b7e7;
|
858 |
+
background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x;
|
859 |
+
font-weight: bold;
|
860 |
+
color: #e17009;
|
861 |
+
}
|
862 |
+
.ui-state-active a,
|
863 |
+
.ui-state-active a:link,
|
864 |
+
.ui-state-active a:visited {
|
865 |
+
color: #e17009;
|
866 |
+
text-decoration: none;
|
867 |
+
}
|
868 |
+
|
869 |
+
/* Interaction Cues
|
870 |
+
----------------------------------*/
|
871 |
+
.ui-state-highlight,
|
872 |
+
.ui-widget-content .ui-state-highlight,
|
873 |
+
.ui-widget-header .ui-state-highlight {
|
874 |
+
border: 1px solid #fad42e;
|
875 |
+
background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x;
|
876 |
+
color: #363636;
|
877 |
+
}
|
878 |
+
.ui-state-highlight a,
|
879 |
+
.ui-widget-content .ui-state-highlight a,
|
880 |
+
.ui-widget-header .ui-state-highlight a {
|
881 |
+
color: #363636;
|
882 |
+
}
|
883 |
+
.ui-state-error,
|
884 |
+
.ui-widget-content .ui-state-error,
|
885 |
+
.ui-widget-header .ui-state-error {
|
886 |
+
border: 1px solid #cd0a0a;
|
887 |
+
background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;
|
888 |
+
color: #cd0a0a;
|
889 |
+
}
|
890 |
+
.ui-state-error a,
|
891 |
+
.ui-widget-content .ui-state-error a,
|
892 |
+
.ui-widget-header .ui-state-error a {
|
893 |
+
color: #cd0a0a;
|
894 |
+
}
|
895 |
+
.ui-state-error-text,
|
896 |
+
.ui-widget-content .ui-state-error-text,
|
897 |
+
.ui-widget-header .ui-state-error-text {
|
898 |
+
color: #cd0a0a;
|
899 |
+
}
|
900 |
+
.ui-priority-primary,
|
901 |
+
.ui-widget-content .ui-priority-primary,
|
902 |
+
.ui-widget-header .ui-priority-primary {
|
903 |
+
font-weight: bold;
|
904 |
+
}
|
905 |
+
.ui-priority-secondary,
|
906 |
+
.ui-widget-content .ui-priority-secondary,
|
907 |
+
.ui-widget-header .ui-priority-secondary {
|
908 |
+
opacity: .7;
|
909 |
+
filter:Alpha(Opacity=70);
|
910 |
+
font-weight: normal;
|
911 |
+
}
|
912 |
+
.ui-state-disabled,
|
913 |
+
.ui-widget-content .ui-state-disabled,
|
914 |
+
.ui-widget-header .ui-state-disabled {
|
915 |
+
opacity: .35;
|
916 |
+
filter:Alpha(Opacity=35);
|
917 |
+
background-image: none;
|
918 |
+
}
|
919 |
+
.ui-state-disabled .ui-icon {
|
920 |
+
filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
|
921 |
+
}
|
922 |
+
|
923 |
+
/* Icons
|
924 |
+
----------------------------------*/
|
925 |
+
|
926 |
+
/* states and images */
|
927 |
+
.ui-icon {
|
928 |
+
width: 16px;
|
929 |
+
height: 16px;
|
930 |
+
background-position: 16px 16px;
|
931 |
+
}
|
932 |
+
.ui-icon,
|
933 |
+
.ui-widget-content .ui-icon {
|
934 |
+
background-image: url(images/ui-icons_469bdd_256x240.png);
|
935 |
+
}
|
936 |
+
.ui-widget-header .ui-icon {
|
937 |
+
background-image: url(images/ui-icons_d8e7f3_256x240.png);
|
938 |
+
}
|
939 |
+
.ui-state-default .ui-icon {
|
940 |
+
background-image: url(images/ui-icons_6da8d5_256x240.png);
|
941 |
+
}
|
942 |
+
.ui-state-hover .ui-icon,
|
943 |
+
.ui-state-focus .ui-icon {
|
944 |
+
background-image: url(images/ui-icons_217bc0_256x240.png);
|
945 |
+
}
|
946 |
+
.ui-state-active .ui-icon {
|
947 |
+
background-image: url(images/ui-icons_f9bd01_256x240.png);
|
948 |
+
}
|
949 |
+
.ui-state-highlight .ui-icon {
|
950 |
+
background-image: url(images/ui-icons_2e83ff_256x240.png);
|
951 |
+
}
|
952 |
+
.ui-state-error .ui-icon,
|
953 |
+
.ui-state-error-text .ui-icon {
|
954 |
+
background-image: url(images/ui-icons_cd0a0a_256x240.png);
|
955 |
+
}
|
956 |
+
|
957 |
+
/* positioning */
|
958 |
+
.ui-icon-carat-1-n { background-position: 0 0; }
|
959 |
+
.ui-icon-carat-1-ne { background-position: -16px 0; }
|
960 |
+
.ui-icon-carat-1-e { background-position: -32px 0; }
|
961 |
+
.ui-icon-carat-1-se { background-position: -48px 0; }
|
962 |
+
.ui-icon-carat-1-s { background-position: -64px 0; }
|
963 |
+
.ui-icon-carat-1-sw { background-position: -80px 0; }
|
964 |
+
.ui-icon-carat-1-w { background-position: -96px 0; }
|
965 |
+
.ui-icon-carat-1-nw { background-position: -112px 0; }
|
966 |
+
.ui-icon-carat-2-n-s { background-position: -128px 0; }
|
967 |
+
.ui-icon-carat-2-e-w { background-position: -144px 0; }
|
968 |
+
.ui-icon-triangle-1-n { background-position: 0 -16px; }
|
969 |
+
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
|
970 |
+
.ui-icon-triangle-1-e { background-position: -32px -16px; }
|
971 |
+
.ui-icon-triangle-1-se { background-position: -48px -16px; }
|
972 |
+
.ui-icon-triangle-1-s { background-position: -64px -16px; }
|
973 |
+
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
|
974 |
+
.ui-icon-triangle-1-w { background-position: -96px -16px; }
|
975 |
+
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
|
976 |
+
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
|
977 |
+
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
|
978 |
+
.ui-icon-arrow-1-n { background-position: 0 -32px; }
|
979 |
+
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
|
980 |
+
.ui-icon-arrow-1-e { background-position: -32px -32px; }
|
981 |
+
.ui-icon-arrow-1-se { background-position: -48px -32px; }
|
982 |
+
.ui-icon-arrow-1-s { background-position: -64px -32px; }
|
983 |
+
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
|
984 |
+
.ui-icon-arrow-1-w { background-position: -96px -32px; }
|
985 |
+
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
|
986 |
+
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
|
987 |
+
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
|
988 |
+
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
|
989 |
+
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
|
990 |
+
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
|
991 |
+
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
|
992 |
+
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
|
993 |
+
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
|
994 |
+
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
|
995 |
+
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
|
996 |
+
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
|
997 |
+
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
|
998 |
+
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
|
999 |
+
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
|
1000 |
+
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
|
1001 |
+
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
|
1002 |
+
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
|
1003 |
+
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
|
1004 |
+
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
|
1005 |
+
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
|
1006 |
+
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
|
1007 |
+
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
|
1008 |
+
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
|
1009 |
+
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
|
1010 |
+
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
|
1011 |
+
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
|
1012 |
+
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
|
1013 |
+
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
|
1014 |
+
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
|
1015 |
+
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
|
1016 |
+
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
|
1017 |
+
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
|
1018 |
+
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
|
1019 |
+
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
|
1020 |
+
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
|
1021 |
+
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
|
1022 |
+
.ui-icon-arrow-4 { background-position: 0 -80px; }
|
1023 |
+
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
|
1024 |
+
.ui-icon-extlink { background-position: -32px -80px; }
|
1025 |
+
.ui-icon-newwin { background-position: -48px -80px; }
|
1026 |
+
.ui-icon-refresh { background-position: -64px -80px; }
|
1027 |
+
.ui-icon-shuffle { background-position: -80px -80px; }
|
1028 |
+
.ui-icon-transfer-e-w { background-position: -96px -80px; }
|
1029 |
+
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
|
1030 |
+
.ui-icon-folder-collapsed { background-position: 0 -96px; }
|
1031 |
+
.ui-icon-folder-open { background-position: -16px -96px; }
|
1032 |
+
.ui-icon-document { background-position: -32px -96px; }
|
1033 |
+
.ui-icon-document-b { background-position: -48px -96px; }
|
1034 |
+
.ui-icon-note { background-position: -64px -96px; }
|
1035 |
+
.ui-icon-mail-closed { background-position: -80px -96px; }
|
1036 |
+
.ui-icon-mail-open { background-position: -96px -96px; }
|
1037 |
+
.ui-icon-suitcase { background-position: -112px -96px; }
|
1038 |
+
.ui-icon-comment { background-position: -128px -96px; }
|
1039 |
+
.ui-icon-person { background-position: -144px -96px; }
|
1040 |
+
.ui-icon-print { background-position: -160px -96px; }
|
1041 |
+
.ui-icon-trash { background-position: -176px -96px; }
|
1042 |
+
.ui-icon-locked { background-position: -192px -96px; }
|
1043 |
+
.ui-icon-unlocked { background-position: -208px -96px; }
|
1044 |
+
.ui-icon-bookmark { background-position: -224px -96px; }
|
1045 |
+
.ui-icon-tag { background-position: -240px -96px; }
|
1046 |
+
.ui-icon-home { background-position: 0 -112px; }
|
1047 |
+
.ui-icon-flag { background-position: -16px -112px; }
|
1048 |
+
.ui-icon-calendar { background-position: -32px -112px; }
|
1049 |
+
.ui-icon-cart { background-position: -48px -112px; }
|
1050 |
+
.ui-icon-pencil { background-position: -64px -112px; }
|
1051 |
+
.ui-icon-clock { background-position: -80px -112px; }
|
1052 |
+
.ui-icon-disk { background-position: -96px -112px; }
|
1053 |
+
.ui-icon-calculator { background-position: -112px -112px; }
|
1054 |
+
.ui-icon-zoomin { background-position: -128px -112px; }
|
1055 |
+
.ui-icon-zoomout { background-position: -144px -112px; }
|
1056 |
+
.ui-icon-search { background-position: -160px -112px; }
|
1057 |
+
.ui-icon-wrench { background-position: -176px -112px; }
|
1058 |
+
.ui-icon-gear { background-position: -192px -112px; }
|
1059 |
+
.ui-icon-heart { background-position: -208px -112px; }
|
1060 |
+
.ui-icon-star { background-position: -224px -112px; }
|
1061 |
+
.ui-icon-link { background-position: -240px -112px; }
|
1062 |
+
.ui-icon-cancel { background-position: 0 -128px; }
|
1063 |
+
.ui-icon-plus { background-position: -16px -128px; }
|
1064 |
+
.ui-icon-plusthick { background-position: -32px -128px; }
|
1065 |
+
.ui-icon-minus { background-position: -48px -128px; }
|
1066 |
+
.ui-icon-minusthick { background-position: -64px -128px; }
|
1067 |
+
.ui-icon-close { background-position: -80px -128px; }
|
1068 |
+
.ui-icon-closethick { background-position: -96px -128px; }
|
1069 |
+
.ui-icon-key { background-position: -112px -128px; }
|
1070 |
+
.ui-icon-lightbulb { background-position: -128px -128px; }
|
1071 |
+
.ui-icon-scissors { background-position: -144px -128px; }
|
1072 |
+
.ui-icon-clipboard { background-position: -160px -128px; }
|
1073 |
+
.ui-icon-copy { background-position: -176px -128px; }
|
1074 |
+
.ui-icon-contact { background-position: -192px -128px; }
|
1075 |
+
.ui-icon-image { background-position: -208px -128px; }
|
1076 |
+
.ui-icon-video { background-position: -224px -128px; }
|
1077 |
+
.ui-icon-script { background-position: -240px -128px; }
|
1078 |
+
.ui-icon-alert { background-position: 0 -144px; }
|
1079 |
+
.ui-icon-info { background-position: -16px -144px; }
|
1080 |
+
.ui-icon-notice { background-position: -32px -144px; }
|
1081 |
+
.ui-icon-help { background-position: -48px -144px; }
|
1082 |
+
.ui-icon-check { background-position: -64px -144px; }
|
1083 |
+
.ui-icon-bullet { background-position: -80px -144px; }
|
1084 |
+
.ui-icon-radio-on { background-position: -96px -144px; }
|
1085 |
+
.ui-icon-radio-off { background-position: -112px -144px; }
|
1086 |
+
.ui-icon-pin-w { background-position: -128px -144px; }
|
1087 |
+
.ui-icon-pin-s { background-position: -144px -144px; }
|
1088 |
+
.ui-icon-play { background-position: 0 -160px; }
|
1089 |
+
.ui-icon-pause { background-position: -16px -160px; }
|
1090 |
+
.ui-icon-seek-next { background-position: -32px -160px; }
|
1091 |
+
.ui-icon-seek-prev { background-position: -48px -160px; }
|
1092 |
+
.ui-icon-seek-end { background-position: -64px -160px; }
|
1093 |
+
.ui-icon-seek-start { background-position: -80px -160px; }
|
1094 |
+
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
|
1095 |
+
.ui-icon-seek-first { background-position: -80px -160px; }
|
1096 |
+
.ui-icon-stop { background-position: -96px -160px; }
|
1097 |
+
.ui-icon-eject { background-position: -112px -160px; }
|
1098 |
+
.ui-icon-volume-off { background-position: -128px -160px; }
|
1099 |
+
.ui-icon-volume-on { background-position: -144px -160px; }
|
1100 |
+
.ui-icon-power { background-position: 0 -176px; }
|
1101 |
+
.ui-icon-signal-diag { background-position: -16px -176px; }
|
1102 |
+
.ui-icon-signal { background-position: -32px -176px; }
|
1103 |
+
.ui-icon-battery-0 { background-position: -48px -176px; }
|
1104 |
+
.ui-icon-battery-1 { background-position: -64px -176px; }
|
1105 |
+
.ui-icon-battery-2 { background-position: -80px -176px; }
|
1106 |
+
.ui-icon-battery-3 { background-position: -96px -176px; }
|
1107 |
+
.ui-icon-circle-plus { background-position: 0 -192px; }
|
1108 |
+
.ui-icon-circle-minus { background-position: -16px -192px; }
|
1109 |
+
.ui-icon-circle-close { background-position: -32px -192px; }
|
1110 |
+
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
|
1111 |
+
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
|
1112 |
+
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
|
1113 |
+
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
|
1114 |
+
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
|
1115 |
+
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
|
1116 |
+
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
|
1117 |
+
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
|
1118 |
+
.ui-icon-circle-zoomin { background-position: -176px -192px; }
|
1119 |
+
.ui-icon-circle-zoomout { background-position: -192px -192px; }
|
1120 |
+
.ui-icon-circle-check { background-position: -208px -192px; }
|
1121 |
+
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
|
1122 |
+
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
|
1123 |
+
.ui-icon-circlesmall-close { background-position: -32px -208px; }
|
1124 |
+
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
|
1125 |
+
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
|
1126 |
+
.ui-icon-squaresmall-close { background-position: -80px -208px; }
|
1127 |
+
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
|
1128 |
+
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
|
1129 |
+
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
|
1130 |
+
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
|
1131 |
+
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
|
1132 |
+
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
|
1133 |
+
|
1134 |
+
|
1135 |
+
/* Misc visuals
|
1136 |
+
----------------------------------*/
|
1137 |
+
|
1138 |
+
/* Corner radius */
|
1139 |
+
.ui-corner-all,
|
1140 |
+
.ui-corner-top,
|
1141 |
+
.ui-corner-left,
|
1142 |
+
.ui-corner-tl {
|
1143 |
+
border-top-left-radius: 5px;
|
1144 |
+
}
|
1145 |
+
.ui-corner-all,
|
1146 |
+
.ui-corner-top,
|
1147 |
+
.ui-corner-right,
|
1148 |
+
.ui-corner-tr {
|
1149 |
+
border-top-right-radius: 5px;
|
1150 |
+
}
|
1151 |
+
.ui-corner-all,
|
1152 |
+
.ui-corner-bottom,
|
1153 |
+
.ui-corner-left,
|
1154 |
+
.ui-corner-bl {
|
1155 |
+
border-bottom-left-radius: 5px;
|
1156 |
+
}
|
1157 |
+
.ui-corner-all,
|
1158 |
+
.ui-corner-bottom,
|
1159 |
+
.ui-corner-right,
|
1160 |
+
.ui-corner-br {
|
1161 |
+
border-bottom-right-radius: 5px;
|
1162 |
+
}
|
1163 |
+
|
1164 |
+
/* Overlays */
|
1165 |
+
.ui-widget-overlay {
|
1166 |
+
background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;
|
1167 |
+
opacity: .3;
|
1168 |
+
filter: Alpha(Opacity=30);
|
1169 |
+
}
|
1170 |
+
.ui-widget-shadow {
|
1171 |
+
margin: -8px 0 0 -8px;
|
1172 |
+
padding: 8px;
|
1173 |
+
background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;
|
1174 |
+
opacity: .3;
|
1175 |
+
filter: Alpha(Opacity=30);
|
1176 |
+
border-radius: 8px;
|
1177 |
+
}
|
static/js/jquery/jquery.mjs.nestedSortable.js
CHANGED
@@ -345,7 +345,7 @@
|
|
345 |
}
|
346 |
|
347 |
if (id) {
|
348 |
-
ret.push({"item_id": id[2], "parent_id": pid, "
|
349 |
}
|
350 |
|
351 |
left = right + 1;
|
345 |
}
|
346 |
|
347 |
if (id) {
|
348 |
+
ret.push({"item_id": id[2], "parent_id": pid, "delim": $(item).parents('.post_taxonomy:first').find('input.tax_delim').val(), "left": left, "right": right, "xpath":$(item).find('input.widefat').val(), "assign":$(item).find('input.assign_post').is(':checked')});
|
349 |
}
|
350 |
|
351 |
left = right + 1;
|
static/js/jquery/moment.js
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// moment.js
|
2 |
+
// version : 1.7.2
|
3 |
+
// author : Tim Wood
|
4 |
+
// license : MIT
|
5 |
+
// momentjs.com
|
6 |
+
(function(a){function E(a,b,c,d){var e=c.lang();return e[a].call?e[a](c,d):e[a][b]}function F(a,b){return function(c){return K(a.call(this,c),b)}}function G(a){return function(b){var c=a.call(this,b);return c+this.lang().ordinal(c)}}function H(a,b,c){this._d=a,this._isUTC=!!b,this._a=a._a||null,this._lang=c||!1}function I(a){var b=this._data={},c=a.years||a.y||0,d=a.months||a.M||0,e=a.weeks||a.w||0,f=a.days||a.d||0,g=a.hours||a.h||0,h=a.minutes||a.m||0,i=a.seconds||a.s||0,j=a.milliseconds||a.ms||0;this._milliseconds=j+i*1e3+h*6e4+g*36e5,this._days=f+e*7,this._months=d+c*12,b.milliseconds=j%1e3,i+=J(j/1e3),b.seconds=i%60,h+=J(i/60),b.minutes=h%60,g+=J(h/60),b.hours=g%24,f+=J(g/24),f+=e*7,b.days=f%30,d+=J(f/30),b.months=d%12,c+=J(d/12),b.years=c,this._lang=!1}function J(a){return a<0?Math.ceil(a):Math.floor(a)}function K(a,b){var c=a+"";while(c.length<b)c="0"+c;return c}function L(a,b,c){var d=b._milliseconds,e=b._days,f=b._months,g;d&&a._d.setTime(+a+d*c),e&&a.date(a.date()+e*c),f&&(g=a.date(),a.date(1).month(a.month()+f*c).date(Math.min(g,a.daysInMonth())))}function M(a){return Object.prototype.toString.call(a)==="[object Array]"}function N(a,b){var c=Math.min(a.length,b.length),d=Math.abs(a.length-b.length),e=0,f;for(f=0;f<c;f++)~~a[f]!==~~b[f]&&e++;return e+d}function O(a,b,c,d){var e,f,g=[];for(e=0;e<7;e++)g[e]=a[e]=a[e]==null?e===2?1:0:a[e];return a[7]=g[7]=b,a[8]!=null&&(g[8]=a[8]),a[3]+=c||0,a[4]+=d||0,f=new Date(0),b?(f.setUTCFullYear(a[0],a[1],a[2]),f.setUTCHours(a[3],a[4],a[5],a[6])):(f.setFullYear(a[0],a[1],a[2]),f.setHours(a[3],a[4],a[5],a[6])),f._a=g,f}function P(a,c){var d,e,g=[];!c&&h&&(c=require("./lang/"+a));for(d=0;d<i.length;d++)c[i[d]]=c[i[d]]||f.en[i[d]];for(d=0;d<12;d++)e=b([2e3,d]),g[d]=new RegExp("^"+(c.months[d]||c.months(e,""))+"|^"+(c.monthsShort[d]||c.monthsShort(e,"")).replace(".",""),"i");return c.monthsParse=c.monthsParse||g,f[a]=c,c}function Q(a){var c=typeof a=="string"&&a||a&&a._lang||null;return c?f[c]||P(c):b}function R(a){return a.match(/\[.*\]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function S(a){var b=a.match(k),c,d;for(c=0,d=b.length;c<d;c++)D[b[c]]?b[c]=D[b[c]]:b[c]=R(b[c]);return function(e){var f="";for(c=0;c<d;c++)f+=typeof b[c].call=="function"?b[c].call(e,a):b[c];return f}}function T(a,b){function d(b){return a.lang().longDateFormat[b]||b}var c=5;while(c--&&l.test(b))b=b.replace(l,d);return A[b]||(A[b]=S(b)),A[b](a)}function U(a){switch(a){case"DDDD":return p;case"YYYY":return q;case"S":case"SS":case"SSS":case"DDD":return o;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":case"a":case"A":return r;case"Z":case"ZZ":return s;case"T":return t;case"MM":case"DD":case"YY":case"HH":case"hh":case"mm":case"ss":case"M":case"D":case"d":case"H":case"h":case"m":case"s":return n;default:return new RegExp(a.replace("\\",""))}}function V(a,b,c,d){var e,f;switch(a){case"M":case"MM":c[1]=b==null?0:~~b-1;break;case"MMM":case"MMMM":for(e=0;e<12;e++)if(Q().monthsParse[e].test(b)){c[1]=e,f=!0;break}f||(c[8]=!1);break;case"D":case"DD":case"DDD":case"DDDD":b!=null&&(c[2]=~~b);break;case"YY":c[0]=~~b+(~~b>70?1900:2e3);break;case"YYYY":c[0]=~~Math.abs(b);break;case"a":case"A":d.isPm=(b+"").toLowerCase()==="pm";break;case"H":case"HH":case"h":case"hh":c[3]=~~b;break;case"m":case"mm":c[4]=~~b;break;case"s":case"ss":c[5]=~~b;break;case"S":case"SS":case"SSS":c[6]=~~(("0."+b)*1e3);break;case"Z":case"ZZ":d.isUTC=!0,e=(b+"").match(x),e&&e[1]&&(d.tzh=~~e[1]),e&&e[2]&&(d.tzm=~~e[2]),e&&e[0]==="+"&&(d.tzh=-d.tzh,d.tzm=-d.tzm)}b==null&&(c[8]=!1)}function W(a,b){var c=[0,0,1,0,0,0,0],d={tzh:0,tzm:0},e=b.match(k),f,g;for(f=0;f<e.length;f++)g=(U(e[f]).exec(a)||[])[0],g&&(a=a.slice(a.indexOf(g)+g.length)),D[e[f]]&&V(e[f],g,c,d);return d.isPm&&c[3]<12&&(c[3]+=12),d.isPm===!1&&c[3]===12&&(c[3]=0),O(c,d.isUTC,d.tzh,d.tzm)}function X(a,b){var c,d=a.match(m)||[],e,f=99,g,h,i;for(g=0;g<b.length;g++)h=W(a,b[g]),e=T(new H(h),b[g]).match(m)||[],i=N(d,e),i<f&&(f=i,c=h);return c}function Y(a){var b="YYYY-MM-DDT",c;if(u.exec(a)){for(c=0;c<4;c++)if(w[c][1].exec(a)){b+=w[c][0];break}return s.exec(a)?W(a,b+" Z"):W(a,b)}return new Date(a)}function Z(a,b,c,d,e){var f=e.relativeTime[a];return typeof f=="function"?f(b||1,!!c,a,d):f.replace(/%d/i,b||1)}function $(a,b,c){var e=d(Math.abs(a)/1e3),f=d(e/60),g=d(f/60),h=d(g/24),i=d(h/365),j=e<45&&["s",e]||f===1&&["m"]||f<45&&["mm",f]||g===1&&["h"]||g<22&&["hh",g]||h===1&&["d"]||h<=25&&["dd",h]||h<=45&&["M"]||h<345&&["MM",d(h/30)]||i===1&&["y"]||["yy",i];return j[2]=b,j[3]=a>0,j[4]=c,Z.apply({},j)}function _(a,c){b.fn[a]=function(a){var b=this._isUTC?"UTC":"";return a!=null?(this._d["set"+b+c](a),this):this._d["get"+b+c]()}}function ab(a){b.duration.fn[a]=function(){return this._data[a]}}function bb(a,c){b.duration.fn["as"+a]=function(){return+this/c}}var b,c="1.7.2",d=Math.round,e,f={},g="en",h=typeof module!="undefined"&&module.exports,i="months|monthsShort|weekdays|weekdaysShort|weekdaysMin|longDateFormat|calendar|relativeTime|ordinal|meridiem".split("|"),j=/^\/?Date\((\-?\d+)/i,k=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|zz?|ZZ?|.)/g,l=/(\[[^\[]*\])|(\\)?(LT|LL?L?L?)/g,m=/([0-9a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)/gi,n=/\d\d?/,o=/\d{1,3}/,p=/\d{3}/,q=/\d{1,4}/,r=/[0-9a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+/i,s=/Z|[\+\-]\d\d:?\d\d/i,t=/T/i,u=/^\s*\d{4}-\d\d-\d\d(T(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/,v="YYYY-MM-DDTHH:mm:ssZ",w=[["HH:mm:ss.S",/T\d\d:\d\d:\d\d\.\d{1,3}/],["HH:mm:ss",/T\d\d:\d\d:\d\d/],["HH:mm",/T\d\d:\d\d/],["HH",/T\d\d/]],x=/([\+\-]|\d\d)/gi,y="Month|Date|Hours|Minutes|Seconds|Milliseconds".split("|"),z={Milliseconds:1,Seconds:1e3,Minutes:6e4,Hours:36e5,Days:864e5,Months:2592e6,Years:31536e6},A={},B="DDD w M D d".split(" "),C="M D H h m s w".split(" "),D={M:function(){return this.month()+1},MMM:function(a){return E("monthsShort",this.month(),this,a)},MMMM:function(a){return E("months",this.month(),this,a)},D:function(){return this.date()},DDD:function(){var a=new Date(this.year(),this.month(),this.date()),b=new Date(this.year(),0,1);return~~((a-b)/864e5+1.5)},d:function(){return this.day()},dd:function(a){return E("weekdaysMin",this.day(),this,a)},ddd:function(a){return E("weekdaysShort",this.day(),this,a)},dddd:function(a){return E("weekdays",this.day(),this,a)},w:function(){var a=new Date(this.year(),this.month(),this.date()-this.day()+5),b=new Date(a.getFullYear(),0,4);return~~((a-b)/864e5/7+1.5)},YY:function(){return K(this.year()%100,2)},YYYY:function(){return K(this.year(),4)},a:function(){return this.lang().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.lang().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return~~(this.milliseconds()/100)},SS:function(){return K(~~(this.milliseconds()/10),2)},SSS:function(){return K(this.milliseconds(),3)},Z:function(){var a=-this.zone(),b="+";return a<0&&(a=-a,b="-"),b+K(~~(a/60),2)+":"+K(~~a%60,2)},ZZ:function(){var a=-this.zone(),b="+";return a<0&&(a=-a,b="-"),b+K(~~(10*a/6),4)}};while(B.length)e=B.pop(),D[e+"o"]=G(D[e]);while(C.length)e=C.pop(),D[e+e]=F(D[e],2);D.DDDD=F(D.DDD,3),b=function(c,d){if(c===null||c==="")return null;var e,f;return b.isMoment(c)?new H(new Date(+c._d),c._isUTC,c._lang):(d?M(d)?e=X(c,d):e=W(c,d):(f=j.exec(c),e=c===a?new Date:f?new Date(+f[1]):c instanceof Date?c:M(c)?O(c):typeof c=="string"?Y(c):new Date(c)),new H(e))},b.utc=function(a,c){return M(a)?new H(O(a,!0),!0):(typeof a=="string"&&!s.exec(a)&&(a+=" +0000",c&&(c+=" Z")),b(a,c).utc())},b.unix=function(a){return b(a*1e3)},b.duration=function(a,c){var d=b.isDuration(a),e=typeof a=="number",f=d?a._data:e?{}:a,g;return e&&(c?f[c]=a:f.milliseconds=a),g=new I(f),d&&(g._lang=a._lang),g},b.humanizeDuration=function(a,c,d){return b.duration(a,c===!0?null:c).humanize(c===!0?!0:d)},b.version=c,b.defaultFormat=v,b.lang=function(a,c){var d;if(!a)return g;(c||!f[a])&&P(a,c);if(f[a]){for(d=0;d<i.length;d++)b[i[d]]=f[a][i[d]];b.monthsParse=f[a].monthsParse,g=a}},b.langData=Q,b.isMoment=function(a){return a instanceof H},b.isDuration=function(a){return a instanceof I},b.lang("en",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D YYYY",LLL:"MMMM D YYYY LT",LLLL:"dddd, MMMM D YYYY LT"},meridiem:function(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinal:function(a){var b=a%10;return~~(a%100/10)===1?"th":b===1?"st":b===2?"nd":b===3?"rd":"th"}}),b.fn=H.prototype={clone:function(){return b(this)},valueOf:function(){return+this._d},unix:function(){return Math.floor(+this._d/1e3)},toString:function(){return this._d.toString()},toDate:function(){return this._d},toArray:function(){var a=this;return[a.year(),a.month(),a.date(),a.hours(),a.minutes(),a.seconds(),a.milliseconds(),!!this._isUTC]},isValid:function(){return this._a?this._a[8]!=null?!!this._a[8]:!N(this._a,(this._a[7]?b.utc(this._a):b(this._a)).toArray()):!isNaN(this._d.getTime())},utc:function(){return this._isUTC=!0,this},local:function(){return this._isUTC=!1,this},format:function(a){return T(this,a?a:b.defaultFormat)},add:function(a,c){var d=c?b.duration(+c,a):b.duration(a);return L(this,d,1),this},subtract:function(a,c){var d=c?b.duration(+c,a):b.duration(a);return L(this,d,-1),this},diff:function(a,c,e){var f=this._isUTC?b(a).utc():b(a).local(),g=(this.zone()-f.zone())*6e4,h=this._d-f._d-g,i=this.year()-f.year(),j=this.month()-f.month(),k=this.date()-f.date(),l;return c==="months"?l=i*12+j+k/30:c==="years"?l=i+(j+k/30)/12:l=c==="seconds"?h/1e3:c==="minutes"?h/6e4:c==="hours"?h/36e5:c==="days"?h/864e5:c==="weeks"?h/6048e5:h,e?l:d(l)},from:function(a,c){return b.duration(this.diff(a)).lang(this._lang).humanize(!c)},fromNow:function(a){return this.from(b(),a)},calendar:function(){var a=this.diff(b().sod(),"days",!0),c=this.lang().calendar,d=c.sameElse,e=a<-6?d:a<-1?c.lastWeek:a<0?c.lastDay:a<1?c.sameDay:a<2?c.nextDay:a<7?c.nextWeek:d;return this.format(typeof e=="function"?e.apply(this):e)},isLeapYear:function(){var a=this.year();return a%4===0&&a%100!==0||a%400===0},isDST:function(){return this.zone()<b([this.year()]).zone()||this.zone()<b([this.year(),5]).zone()},day:function(a){var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return a==null?b:this.add({d:a-b})},startOf:function(a){switch(a.replace(/s$/,"")){case"year":this.month(0);case"month":this.date(1);case"day":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return this},endOf:function(a){return this.startOf(a).add(a.replace(/s?$/,"s"),1).subtract("ms",1)},sod:function(){return this.clone().startOf("day")},eod:function(){return this.clone().endOf("day")},zone:function(){return this._isUTC?0:this._d.getTimezoneOffset()},daysInMonth:function(){return b.utc([this.year(),this.month()+1,0]).date()},lang:function(b){return b===a?Q(this):(this._lang=b,this)}};for(e=0;e<y.length;e++)_(y[e].toLowerCase(),y[e]);_("year","FullYear"),b.duration.fn=I.prototype={weeks:function(){return J(this.days()/7)},valueOf:function(){return this._milliseconds+this._days*864e5+this._months*2592e6},humanize:function(a){var b=+this,c=this.lang().relativeTime,d=$(b,!a,this.lang()),e=b<=0?c.past:c.future;return a&&(typeof e=="function"?d=e(d):d=e.replace(/%s/i,d)),d},lang:b.fn.lang};for(e in z)z.hasOwnProperty(e)&&(bb(e,z[e]),ab(e.toLowerCase()));bb("Weeks",6048e5),h&&(module.exports=b),typeof ender=="undefined"&&(this.moment=b),typeof define=="function"&&define.amd&&define("moment",[],function(){return b})}).call(this);
|
static/js/plupload/plupload.flash.swf
ADDED
Binary file
|
static/js/plupload/plupload.full.js
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
/*1.5b*/
|
2 |
+
(function(){var f=0,l=[],n={},j={},a={"<":"lt",">":"gt","&":"amp",'"':"quot","'":"#39"},m=/[<>&\"\']/g,b,c=window.setTimeout,d={},e;function h(){this.returnValue=false}function k(){this.cancelBubble=true}(function(o){var p=o.split(/,/),q,s,r;for(q=0;q<p.length;q+=2){r=p[q+1].split(/ /);for(s=0;s<r.length;s++){j[r[s]]=p[q]}}})("application/msword,doc dot,application/pdf,pdf,application/pgp-signature,pgp,application/postscript,ps ai eps,application/rtf,rtf,application/vnd.ms-excel,xls xlb,application/vnd.ms-powerpoint,ppt pps pot,application/zip,zip,application/x-shockwave-flash,swf swfl,application/vnd.openxmlformats,docx pptx xlsx,audio/mpeg,mpga mpega mp2 mp3,audio/x-wav,wav,audio/mp4,m4a,image/bmp,bmp,image/gif,gif,image/jpeg,jpeg jpg jpe,image/photoshop,psd,image/png,png,image/svg+xml,svg svgz,image/tiff,tiff tif,text/html,htm html xhtml,text/rtf,rtf,video/mpeg,mpeg mpg mpe,video/quicktime,qt mov,video/mp4,mp4,video/x-m4v,m4v,video/x-flv,flv,video/x-ms-wmv,wmv,video/avi,avi,video/webm,webm,video/vnd.rn-realvideo,rv,text/csv,csv,text/plain,asc txt text diff log,application/octet-stream,exe");var g={VERSION:"1.5b",STOPPED:1,STARTED:2,QUEUED:1,UPLOADING:2,FAILED:4,DONE:5,GENERIC_ERROR:-100,HTTP_ERROR:-200,IO_ERROR:-300,SECURITY_ERROR:-400,INIT_ERROR:-500,FILE_SIZE_ERROR:-600,FILE_EXTENSION_ERROR:-601,IMAGE_FORMAT_ERROR:-700,IMAGE_MEMORY_ERROR:-701,IMAGE_DIMENSIONS_ERROR:-702,mimeTypes:j,extend:function(o){g.each(arguments,function(p,q){if(q>0){g.each(p,function(s,r){o[r]=s})}});return o},cleanName:function(o){var p,q;q=[/[\300-\306]/g,"A",/[\340-\346]/g,"a",/\307/g,"C",/\347/g,"c",/[\310-\313]/g,"E",/[\350-\353]/g,"e",/[\314-\317]/g,"I",/[\354-\357]/g,"i",/\321/g,"N",/\361/g,"n",/[\322-\330]/g,"O",/[\362-\370]/g,"o",/[\331-\334]/g,"U",/[\371-\374]/g,"u"];for(p=0;p<q.length;p+=2){o=o.replace(q[p],q[p+1])}o=o.replace(/\s+/g,"_");o=o.replace(/[^a-z0-9_\-\.]+/gi,"");return o},addRuntime:function(o,p){p.name=o;l[o]=p;l.push(p);return p},guid:function(){var o=new Date().getTime().toString(32),p;for(p=0;p<5;p++){o+=Math.floor(Math.random()*65535).toString(32)}return(g.guidPrefix||"p")+o+(f++).toString(32)},buildUrl:function(p,o){var q="";g.each(o,function(s,r){q+=(q?"&":"")+encodeURIComponent(r)+"="+encodeURIComponent(s)});if(q){p+=(p.indexOf("?")>0?"&":"?")+q}return p},each:function(r,s){var q,p,o;if(r){q=r.length;if(q===b){for(p in r){if(r.hasOwnProperty(p)){if(s(r[p],p)===false){return}}}}else{for(o=0;o<q;o++){if(s(r[o],o)===false){return}}}}},formatSize:function(o){if(o===b||/\D/.test(o)){return g.translate("N/A")}if(o>1073741824){return Math.round(o/1073741824,1)+" GB"}if(o>1048576){return Math.round(o/1048576,1)+" MB"}if(o>1024){return Math.round(o/1024,1)+" KB"}return o+" b"},getPos:function(p,t){var u=0,s=0,w,v=document,q,r;p=p;t=t||v.body;function o(C){var A,B,z=0,D=0;if(C){B=C.getBoundingClientRect();A=v.compatMode==="CSS1Compat"?v.documentElement:v.body;z=B.left+A.scrollLeft;D=B.top+A.scrollTop}return{x:z,y:D}}if(p&&p.getBoundingClientRect&&(navigator.userAgent.indexOf("MSIE")>0&&v.documentMode!==8)){q=o(p);r=o(t);return{x:q.x-r.x,y:q.y-r.y}}w=p;while(w&&w!=t&&w.nodeType){u+=w.offsetLeft||0;s+=w.offsetTop||0;w=w.offsetParent}w=p.parentNode;while(w&&w!=t&&w.nodeType){u-=w.scrollLeft||0;s-=w.scrollTop||0;w=w.parentNode}return{x:u,y:s}},getSize:function(o){return{w:o.offsetWidth||o.clientWidth,h:o.offsetHeight||o.clientHeight}},parseSize:function(o){var p;if(typeof(o)=="string"){o=/^([0-9]+)([mgk]?)$/.exec(o.toLowerCase().replace(/[^0-9mkg]/g,""));p=o[2];o=+o[1];if(p=="g"){o*=1073741824}if(p=="m"){o*=1048576}if(p=="k"){o*=1024}}return o},xmlEncode:function(o){return o?(""+o).replace(m,function(p){return a[p]?"&"+a[p]+";":p}):o},toArray:function(q){var p,o=[];for(p=0;p<q.length;p++){o[p]=q[p]}return o},addI18n:function(o){return g.extend(n,o)},translate:function(o){return n[o]||o},isEmptyObj:function(o){if(o===b){return true}for(var p in o){return false}return true},hasClass:function(q,p){var o;if(q.className==""){return false}o=new RegExp("(^|\\s+)"+p+"(\\s+|$)");return o.test(q.className)},addClass:function(p,o){if(!g.hasClass(p,o)){p.className=p.className==""?o:p.className.replace(/\s+$/,"")+" "+o}},removeClass:function(q,p){var o=new RegExp("(^|\\s+)"+p+"(\\s+|$)");q.className=q.className.replace(o,function(s,r,t){return r===" "&&t===" "?" ":""})},getStyle:function(p,o){if(p.currentStyle){return p.currentStyle[o]}else{if(window.getComputedStyle){return window.getComputedStyle(p,null)[o]}}},addEvent:function(t,o,u){var s,r,q,p;p=arguments[3];o=o.toLowerCase();if(e===b){e="Plupload_"+g.guid()}if(t.addEventListener){s=u;t.addEventListener(o,s,false)}else{if(t.attachEvent){s=function(){var v=window.event;if(!v.target){v.target=v.srcElement}v.preventDefault=h;v.stopPropagation=k;u(v)};t.attachEvent("on"+o,s)}}if(t[e]===b){t[e]=g.guid()}if(!d.hasOwnProperty(t[e])){d[t[e]]={}}r=d[t[e]];if(!r.hasOwnProperty(o)){r[o]=[]}r[o].push({func:s,orig:u,key:p})},removeEvent:function(t,o){var r,u,q;if(typeof(arguments[2])=="function"){u=arguments[2]}else{q=arguments[2]}o=o.toLowerCase();if(t[e]&&d[t[e]]&&d[t[e]][o]){r=d[t[e]][o]}else{return}for(var p=r.length-1;p>=0;p--){if(r[p].key===q||r[p].orig===u){if(t.detachEvent){t.detachEvent("on"+o,r[p].func)}else{if(t.removeEventListener){t.removeEventListener(o,r[p].func,false)}}r[p].orig=null;r[p].func=null;r.splice(p,1);if(u!==b){break}}}if(!r.length){delete d[t[e]][o]}if(g.isEmptyObj(d[t[e]])){delete d[t[e]];try{delete t[e]}catch(s){t[e]=b}}},removeAllEvents:function(p){var o=arguments[1];if(p[e]===b||!p[e]){return}g.each(d[p[e]],function(r,q){g.removeEvent(p,q,o)})}};g.Uploader=function(r){var p={},u,t=[],q;u=new g.QueueProgress();r=g.extend({chunk_size:0,multipart:true,multi_selection:true,file_data_name:"file",filters:[]},r);function s(){var w,x=0,v;if(this.state==g.STARTED){for(v=0;v<t.length;v++){if(!w&&t[v].status==g.QUEUED){w=t[v];w.status=g.UPLOADING;if(this.trigger("BeforeUpload",w)){this.trigger("UploadFile",w)}}else{x++}}if(x==t.length){this.trigger("UploadComplete",t);this.stop()}}}function o(){var w,v;u.reset();for(w=0;w<t.length;w++){v=t[w];if(v.size!==b){u.size+=v.size;u.loaded+=v.loaded}else{u.size=b}if(v.status==g.DONE){u.uploaded++}else{if(v.status==g.FAILED){u.failed++}else{u.queued++}}}if(u.size===b){u.percent=t.length>0?Math.ceil(u.uploaded/t.length*100):0}else{u.bytesPerSec=Math.ceil(u.loaded/((+new Date()-q||1)/1000));u.percent=u.size>0?Math.ceil(u.loaded/u.size*100):0}}g.extend(this,{state:g.STOPPED,runtime:"",features:{},files:t,settings:r,total:u,id:g.guid(),init:function(){var A=this,B,x,w,z=0,y;if(typeof(r.preinit)=="function"){r.preinit(A)}else{g.each(r.preinit,function(D,C){A.bind(C,D)})}r.page_url=r.page_url||document.location.pathname.replace(/\/[^\/]+$/g,"/");if(!/^(\w+:\/\/|\/)/.test(r.url)){r.url=r.page_url+r.url}r.chunk_size=g.parseSize(r.chunk_size);r.max_file_size=g.parseSize(r.max_file_size);A.bind("FilesAdded",function(C,F){var E,D,H=0,I,G=r.filters;if(G&&G.length){I=[];g.each(G,function(J){g.each(J.extensions.split(/,/),function(K){if(/^\s*\*\s*$/.test(K)){I.push("\\.*")}else{I.push("\\."+K.replace(new RegExp("["+("/^$.*+?|()[]{}\\".replace(/./g,"\\$&"))+"]","g"),"\\$&"))}})});I=new RegExp(I.join("|")+"$","i")}for(E=0;E<F.length;E++){D=F[E];D.loaded=0;D.percent=0;D.status=g.QUEUED;if(I&&!I.test(D.name)){C.trigger("Error",{code:g.FILE_EXTENSION_ERROR,message:g.translate("File extension error."),file:D});continue}if(D.size!==b&&D.size>r.max_file_size){C.trigger("Error",{code:g.FILE_SIZE_ERROR,message:g.translate("File size error."),file:D});continue}t.push(D);H++}if(H){c(function(){A.trigger("QueueChanged");A.refresh()},1)}else{return false}});if(r.unique_names){A.bind("UploadFile",function(C,D){var F=D.name.match(/\.([^.]+)$/),E="tmp";if(F){E=F[1]}D.target_name=D.id+"."+E})}A.bind("UploadProgress",function(C,D){D.percent=D.size>0?Math.ceil(D.loaded/D.size*100):100;o()});A.bind("StateChanged",function(C){if(C.state==g.STARTED){q=(+new Date())}else{if(C.state==g.STOPPED){for(B=C.files.length-1;B>=0;B--){if(C.files[B].status==g.UPLOADING){C.files[B].status=g.QUEUED;o()}}}}});A.bind("QueueChanged",o);A.bind("Error",function(C,D){if(D.file){D.file.status=g.FAILED;o();if(C.state==g.STARTED){c(function(){s.call(A)},1)}}});A.bind("FileUploaded",function(C,D){D.status=g.DONE;D.loaded=D.size;C.trigger("UploadProgress",D);c(function(){s.call(A)},1)});if(r.runtimes){x=[];y=r.runtimes.split(/\s?,\s?/);for(B=0;B<y.length;B++){if(l[y[B]]){x.push(l[y[B]])}}}else{x=l}function v(){var F=x[z++],E,C,D;if(F){E=F.getFeatures();C=A.settings.required_features;if(C){C=C.split(",");for(D=0;D<C.length;D++){if(!E[C[D]]){v();return}}}F.init(A,function(G){if(G&&G.success){A.features=E;A.runtime=F.name;A.trigger("Init",{runtime:F.name});A.trigger("PostInit");A.refresh()}else{v()}})}else{A.trigger("Error",{code:g.INIT_ERROR,message:g.translate("Init error.")})}}v();if(typeof(r.init)=="function"){r.init(A)}else{g.each(r.init,function(D,C){A.bind(C,D)})}},refresh:function(){this.trigger("Refresh")},start:function(){if(this.state!=g.STARTED){this.state=g.STARTED;this.trigger("StateChanged");s.call(this)}},stop:function(){if(this.state!=g.STOPPED){this.state=g.STOPPED;this.trigger("StateChanged")}},getFile:function(w){var v;for(v=t.length-1;v>=0;v--){if(t[v].id===w){return t[v]}}},removeFile:function(w){var v;for(v=t.length-1;v>=0;v--){if(t[v].id===w.id){return this.splice(v,1)[0]}}},splice:function(x,v){var w;w=t.splice(x===b?0:x,v===b?t.length:v);this.trigger("FilesRemoved",w);this.trigger("QueueChanged");return w},trigger:function(w){var y=p[w.toLowerCase()],x,v;if(y){v=Array.prototype.slice.call(arguments);v[0]=this;for(x=0;x<y.length;x++){if(y[x].func.apply(y[x].scope,v)===false){return false}}}return true},hasEventListener:function(v){return !!p[v.toLowerCase()]},bind:function(v,x,w){var y;v=v.toLowerCase();y=p[v]||[];y.push({func:x,scope:w||this});p[v]=y},unbind:function(v){v=v.toLowerCase();var y=p[v],w,x=arguments[1];if(y){if(x!==b){for(w=y.length-1;w>=0;w--){if(y[w].func===x){y.splice(w,1);break}}}else{y=[]}if(!y.length){delete p[v]}}},unbindAll:function(){var v=this;g.each(p,function(x,w){v.unbind(w)})},destroy:function(){this.trigger("Destroy");this.unbindAll()}})};g.File=function(r,p,q){var o=this;o.id=r;o.name=p;o.size=q;o.loaded=0;o.percent=0;o.status=0};g.Runtime=function(){this.getFeatures=function(){};this.init=function(o,p){}};g.QueueProgress=function(){var o=this;o.size=0;o.loaded=0;o.uploaded=0;o.failed=0;o.queued=0;o.percent=0;o.bytesPerSec=0;o.reset=function(){o.size=o.loaded=o.uploaded=o.failed=o.queued=o.percent=o.bytesPerSec=0}};g.runtimes={};window.plupload=g})();(function(){if(window.google&&google.gears){return}var a=null;if(typeof GearsFactory!="undefined"){a=new GearsFactory()}else{try{a=new ActiveXObject("Gears.Factory");if(a.getBuildInfo().indexOf("ie_mobile")!=-1){a.privateSetGlobalObject(this)}}catch(b){if((typeof navigator.mimeTypes!="undefined")&&navigator.mimeTypes["application/x-googlegears"]){a=document.createElement("object");a.style.display="none";a.width=0;a.height=0;a.type="application/x-googlegears";document.documentElement.appendChild(a)}}}if(!a){return}if(!window.google){window.google={}}if(!google.gears){google.gears={factory:a}}})();(function(e,b,c,d){var f={};function a(h,k,m){var g,j,l,o;j=google.gears.factory.create("beta.canvas");try{j.decode(h);if(!k.width){k.width=j.width}if(!k.height){k.height=j.height}o=Math.min(width/j.width,height/j.height);if(o<1||(o===1&&m==="image/jpeg")){j.resize(Math.round(j.width*o),Math.round(j.height*o));if(k.quality){return j.encode(m,{quality:k.quality/100})}return j.encode(m)}}catch(n){}return h}c.runtimes.Gears=c.addRuntime("gears",{getFeatures:function(){return{dragdrop:true,jpgresize:true,pngresize:true,chunks:true,progress:true,multipart:true}},init:function(j,l){var k;if(!e.google||!google.gears){return l({success:false})}try{k=google.gears.factory.create("beta.desktop")}catch(h){return l({success:false})}function g(o){var n,m,p=[],q;for(m=0;m<o.length;m++){n=o[m];q=c.guid();f[q]=n.blob;p.push(new c.File(q,n.name,n.blob.length))}j.trigger("FilesAdded",p)}j.bind("PostInit",function(){var n=j.settings,m=b.getElementById(n.drop_element);if(m){c.addEvent(m,"dragover",function(o){k.setDropEffect(o,"copy");o.preventDefault()},j.id);c.addEvent(m,"drop",function(p){var o=k.getDragData(p,"application/x-gears-files");if(o){g(o.files)}p.preventDefault()},j.id);m=0}c.addEvent(b.getElementById(n.browse_button),"click",function(s){var r=[],p,o,q;s.preventDefault();no_type_restriction:for(p=0;p<n.filters.length;p++){q=n.filters[p].extensions.split(",");for(o=0;o<q.length;o++){if(q[o]==="*"){r=[];break no_type_restriction}r.push("."+q[o])}}k.openFiles(g,{singleFile:!n.multi_selection,filter:r})},j.id)});j.bind("UploadFile",function(s,p){var u=0,t,q,r=0,o=s.settings.resize,m;if(o&&/\.(png|jpg|jpeg)$/i.test(p.name)){f[p.id]=a(f[p.id],o,/\.png$/i.test(p.name)?"image/png":"image/jpeg")}p.size=f[p.id].length;q=s.settings.chunk_size;m=q>0;t=Math.ceil(p.size/q);if(!m){q=p.size;t=1}function n(){var z,B,w=s.settings.multipart,v=0,A={name:p.target_name||p.name},x=s.settings.url;function y(D){var C,I="----pluploadboundary"+c.guid(),F="--",H="\r\n",E,G;if(w){z.setRequestHeader("Content-Type","multipart/form-data; boundary="+I);C=google.gears.factory.create("beta.blobbuilder");c.each(c.extend(A,s.settings.multipart_params),function(K,J){C.append(F+I+H+'Content-Disposition: form-data; name="'+J+'"'+H+H);C.append(K+H)});G=c.mimeTypes[p.name.replace(/^.+\.([^.]+)/,"$1").toLowerCase()]||"application/octet-stream";C.append(F+I+H+'Content-Disposition: form-data; name="'+s.settings.file_data_name+'"; filename="'+p.name+'"'+H+"Content-Type: "+G+H+H);C.append(D);C.append(H+F+I+F+H);E=C.getAsBlob();v=E.length-D.length;D=E}z.send(D)}if(p.status==c.DONE||p.status==c.FAILED||s.state==c.STOPPED){return}if(m){A.chunk=u;A.chunks=t}B=Math.min(q,p.size-(u*q));if(!w){x=c.buildUrl(s.settings.url,A)}z=google.gears.factory.create("beta.httprequest");z.open("POST",x);if(!w){z.setRequestHeader("Content-Disposition",'attachment; filename="'+p.name+'"');z.setRequestHeader("Content-Type","application/octet-stream")}c.each(s.settings.headers,function(D,C){z.setRequestHeader(C,D)});z.upload.onprogress=function(C){p.loaded=r+C.loaded-v;s.trigger("UploadProgress",p)};z.onreadystatechange=function(){var C;if(z.readyState==4){if(z.status==200){C={chunk:u,chunks:t,response:z.responseText,status:z.status};s.trigger("ChunkUploaded",p,C);if(C.cancelled){p.status=c.FAILED;return}r+=B;if(++u>=t){p.status=c.DONE;s.trigger("FileUploaded",p,{response:z.responseText,status:z.status})}else{n()}}else{s.trigger("Error",{code:c.HTTP_ERROR,message:c.translate("HTTP Error."),file:p,chunk:u,chunks:t,status:z.status})}}};if(u<t){y(f[p.id].slice(u*q,B))}}n()});j.bind("Destroy",function(m){var n,o,p={browseButton:m.settings.browse_button,dropElm:m.settings.drop_element};for(n in p){o=b.getElementById(p[n]);if(o){c.removeAllEvents(o,m.id)}}});l({success:true})}})})(window,document,plupload);(function(g,b,d,e){var a={},h={};function c(o){var n,m=typeof o,j,l,k;if(o===e||o===null){return"null"}if(m==="string"){n="\bb\tt\nn\ff\rr\"\"''\\\\";return'"'+o.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g,function(r,q){var p=n.indexOf(q);if(p+1){return"\\"+n.charAt(p+1)}r=q.charCodeAt().toString(16);return"\\u"+"0000".substring(r.length)+r})+'"'}if(m=="object"){j=o.length!==e;n="";if(j){for(l=0;l<o.length;l++){if(n){n+=","}n+=c(o[l])}n="["+n+"]"}else{for(k in o){if(o.hasOwnProperty(k)){if(n){n+=","}n+=c(k)+":"+c(o[k])}}n="{"+n+"}"}return n}return""+o}function f(s){var v=false,j=null,o=null,k,l,m,u,n,q=0;try{try{o=new ActiveXObject("AgControl.AgControl");if(o.IsVersionSupported(s)){v=true}o=null}catch(r){var p=navigator.plugins["Silverlight Plug-In"];if(p){k=p.description;if(k==="1.0.30226.2"){k="2.0.30226.2"}l=k.split(".");while(l.length>3){l.pop()}while(l.length<4){l.push(0)}m=s.split(".");while(m.length>4){m.pop()}do{u=parseInt(m[q],10);n=parseInt(l[q],10);q++}while(q<m.length&&u===n);if(u<=n&&!isNaN(u)){v=true}}}}catch(t){v=false}return v}d.silverlight={trigger:function(n,k){var m=a[n],l,j;if(m){j=d.toArray(arguments).slice(1);j[0]="Silverlight:"+k;setTimeout(function(){m.trigger.apply(m,j)},0)}}};d.runtimes.Silverlight=d.addRuntime("silverlight",{getFeatures:function(){return{jpgresize:true,pngresize:true,chunks:true,progress:true,multipart:true}},init:function(p,q){var o,m="",n=p.settings.filters,l,k=b.body;if(!f("2.0.31005.0")||(g.opera&&g.opera.buildNumber)){q({success:false});return}h[p.id]=false;a[p.id]=p;o=b.createElement("div");o.id=p.id+"_silverlight_container";d.extend(o.style,{position:"absolute",top:"0px",background:p.settings.shim_bgcolor||"transparent",zIndex:99999,width:"100px",height:"100px",overflow:"hidden",opacity:p.settings.shim_bgcolor||b.documentMode>8?"":0.01});o.className="plupload silverlight";if(p.settings.container){k=b.getElementById(p.settings.container);if(d.getStyle(k,"position")==="static"){k.style.position="relative"}}k.appendChild(o);for(l=0;l<n.length;l++){m+=(m!=""?"|":"")+n[l].title+" | *."+n[l].extensions.replace(/,/g,";*.")}o.innerHTML='<object id="'+p.id+'_silverlight" data="data:application/x-silverlight," type="application/x-silverlight-2" style="outline:none;" width="1024" height="1024"><param name="source" value="'+p.settings.silverlight_xap_url+'"/><param name="background" value="Transparent"/><param name="windowless" value="true"/><param name="enablehtmlaccess" value="true"/><param name="initParams" value="id='+p.id+",filter="+m+",multiselect="+p.settings.multi_selection+'"/></object>';function j(){return b.getElementById(p.id+"_silverlight").content.Upload}p.bind("Silverlight:Init",function(){var r,s={};if(h[p.id]){return}h[p.id]=true;p.bind("Silverlight:StartSelectFiles",function(t){r=[]});p.bind("Silverlight:SelectFile",function(t,w,u,v){var x;x=d.guid();s[x]=w;s[w]=x;r.push(new d.File(x,u,v))});p.bind("Silverlight:SelectSuccessful",function(){if(r.length){p.trigger("FilesAdded",r)}});p.bind("Silverlight:UploadChunkError",function(t,w,u,x,v){p.trigger("Error",{code:d.IO_ERROR,message:"IO Error.",details:v,file:t.getFile(s[w])})});p.bind("Silverlight:UploadFileProgress",function(t,x,u,w){var v=t.getFile(s[x]);if(v.status!=d.FAILED){v.size=w;v.loaded=u;t.trigger("UploadProgress",v)}});p.bind("Refresh",function(t){var u,v,w;u=b.getElementById(t.settings.browse_button);if(u){v=d.getPos(u,b.getElementById(t.settings.container));w=d.getSize(u);d.extend(b.getElementById(t.id+"_silverlight_container").style,{top:v.y+"px",left:v.x+"px",width:w.w+"px",height:w.h+"px"})}});p.bind("Silverlight:UploadChunkSuccessful",function(t,w,u,z,y){var x,v=t.getFile(s[w]);x={chunk:u,chunks:z,response:y};t.trigger("ChunkUploaded",v,x);if(v.status!=d.FAILED){j().UploadNextChunk()}if(u==z-1){v.status=d.DONE;t.trigger("FileUploaded",v,{response:y})}});p.bind("Silverlight:UploadSuccessful",function(t,w,u){var v=t.getFile(s[w]);v.status=d.DONE;t.trigger("FileUploaded",v,{response:u})});p.bind("FilesRemoved",function(t,v){var u;for(u=0;u<v.length;u++){j().RemoveFile(s[v[u].id])}});p.bind("UploadFile",function(t,v){var w=t.settings,u=w.resize||{};j().UploadFile(s[v.id],t.settings.url,c({name:v.target_name||v.name,mime:d.mimeTypes[v.name.replace(/^.+\.([^.]+)/,"$1").toLowerCase()]||"application/octet-stream",chunk_size:w.chunk_size,image_width:u.width,image_height:u.height,image_quality:u.quality||90,multipart:!!w.multipart,multipart_params:w.multipart_params||{},file_data_name:w.file_data_name,headers:w.headers}))});p.bind("Silverlight:MouseEnter",function(t){var u,v;u=b.getElementById(p.settings.browse_button);v=t.settings.browse_button_hover;if(u&&v){d.addClass(u,v)}});p.bind("Silverlight:MouseLeave",function(t){var u,v;u=b.getElementById(p.settings.browse_button);v=t.settings.browse_button_hover;if(u&&v){d.removeClass(u,v)}});p.bind("Silverlight:MouseLeftButtonDown",function(t){var u,v;u=b.getElementById(p.settings.browse_button);v=t.settings.browse_button_active;if(u&&v){d.addClass(u,v);d.addEvent(b.body,"mouseup",function(){d.removeClass(u,v)})}});p.bind("Sliverlight:StartSelectFiles",function(t){var u,v;u=b.getElementById(p.settings.browse_button);v=t.settings.browse_button_active;if(u&&v){d.removeClass(u,v)}});p.bind("Destroy",function(t){var u;d.removeAllEvents(b.body,t.id);delete h[t.id];delete a[t.id];u=b.getElementById(t.id+"_silverlight_container");if(u){k.removeChild(u)}});q({success:true})})}})})(window,document,plupload);(function(f,b,d,e){var a={},g={};function c(){var h;try{h=navigator.plugins["Shockwave Flash"];h=h.description}catch(k){try{h=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version")}catch(j){h="0.0"}}h=h.match(/\d+/g);return parseFloat(h[0]+"."+h[1])}d.flash={trigger:function(k,h,j){setTimeout(function(){var n=a[k],m,l;if(n){n.trigger("Flash:"+h,j)}},0)}};d.runtimes.Flash=d.addRuntime("flash",{getFeatures:function(){return{jpgresize:true,pngresize:true,maxWidth:8091,maxHeight:8091,chunks:true,progress:true,multipart:true}},init:function(k,p){var o,j,l,q=0,h=b.body;if(c()<10){p({success:false});return}g[k.id]=false;a[k.id]=k;o=b.getElementById(k.settings.browse_button);j=b.createElement("div");j.id=k.id+"_flash_container";d.extend(j.style,{position:"absolute",top:"0px",background:k.settings.shim_bgcolor||"transparent",zIndex:99999,width:"100%",height:"100%"});j.className="plupload flash";if(k.settings.container){h=b.getElementById(k.settings.container);if(d.getStyle(h,"position")==="static"){h.style.position="relative"}}h.appendChild(j);l="id="+escape(k.id);j.innerHTML='<object id="'+k.id+'_flash" width="100%" height="100%" style="outline:0" type="application/x-shockwave-flash" data="'+k.settings.flash_swf_url+'"><param name="movie" value="'+k.settings.flash_swf_url+'" /><param name="flashvars" value="'+l+'" /><param name="wmode" value="transparent" /><param name="allowscriptaccess" value="always" /></object>';function n(){return b.getElementById(k.id+"_flash")}function m(){if(q++>5000){p({success:false});return}if(!g[k.id]){setTimeout(m,1)}}m();o=j=null;k.bind("Flash:Init",function(){var s={},r;n().setFileFilters(k.settings.filters,k.settings.multi_selection);if(g[k.id]){return}g[k.id]=true;k.bind("UploadFile",function(t,v){var w=t.settings,u=k.settings.resize||{};n().uploadFile(s[v.id],w.url,{name:v.target_name||v.name,mime:d.mimeTypes[v.name.replace(/^.+\.([^.]+)/,"$1").toLowerCase()]||"application/octet-stream",chunk_size:w.chunk_size,width:u.width,height:u.height,quality:u.quality,multipart:w.multipart,multipart_params:w.multipart_params||{},file_data_name:w.file_data_name,format:/\.(jpg|jpeg)$/i.test(v.name)?"jpg":"png",headers:w.headers,urlstream_upload:w.urlstream_upload})});k.bind("Flash:UploadProcess",function(u,t){var v=u.getFile(s[t.id]);if(v.status!=d.FAILED){v.loaded=t.loaded;v.size=t.size;u.trigger("UploadProgress",v)}});k.bind("Flash:UploadChunkComplete",function(t,v){var w,u=t.getFile(s[v.id]);w={chunk:v.chunk,chunks:v.chunks,response:v.text};t.trigger("ChunkUploaded",u,w);if(u.status!=d.FAILED){n().uploadNextChunk()}if(v.chunk==v.chunks-1){u.status=d.DONE;t.trigger("FileUploaded",u,{response:v.text})}});k.bind("Flash:SelectFiles",function(t,w){var v,u,x=[],y;for(u=0;u<w.length;u++){v=w[u];y=d.guid();s[y]=v.id;s[v.id]=y;x.push(new d.File(y,v.name,v.size))}if(x.length){k.trigger("FilesAdded",x)}});k.bind("Flash:SecurityError",function(t,u){k.trigger("Error",{code:d.SECURITY_ERROR,message:d.translate("Security error."),details:u.message,file:k.getFile(s[u.id])})});k.bind("Flash:GenericError",function(t,u){k.trigger("Error",{code:d.GENERIC_ERROR,message:d.translate("Generic error."),details:u.message,file:k.getFile(s[u.id])})});k.bind("Flash:IOError",function(t,u){k.trigger("Error",{code:d.IO_ERROR,message:d.translate("IO error."),details:u.message,file:k.getFile(s[u.id])})});k.bind("Flash:ImageError",function(t,u){k.trigger("Error",{code:parseInt(u.code,10),message:d.translate("Image error."),file:k.getFile(s[u.id])})});k.bind("Flash:StageEvent:rollOver",function(t){var u,v;u=b.getElementById(k.settings.browse_button);v=t.settings.browse_button_hover;if(u&&v){d.addClass(u,v)}});k.bind("Flash:StageEvent:rollOut",function(t){var u,v;u=b.getElementById(k.settings.browse_button);v=t.settings.browse_button_hover;if(u&&v){d.removeClass(u,v)}});k.bind("Flash:StageEvent:mouseDown",function(t){var u,v;u=b.getElementById(k.settings.browse_button);v=t.settings.browse_button_active;if(u&&v){d.addClass(u,v);d.addEvent(b.body,"mouseup",function(){d.removeClass(u,v)},t.id)}});k.bind("Flash:StageEvent:mouseUp",function(t){var u,v;u=b.getElementById(k.settings.browse_button);v=t.settings.browse_button_active;if(u&&v){d.removeClass(u,v)}});k.bind("Flash:ExifData",function(t,u){k.trigger("ExifData",k.getFile(s[u.id]),u.data)});k.bind("Flash:GpsData",function(t,u){k.trigger("GpsData",k.getFile(s[u.id]),u.data)});k.bind("QueueChanged",function(t){k.refresh()});k.bind("FilesRemoved",function(t,v){var u;for(u=0;u<v.length;u++){n().removeFile(s[v[u].id])}});k.bind("StateChanged",function(t){k.refresh()});k.bind("Refresh",function(t){var u,v,w;n().setFileFilters(k.settings.filters,k.settings.multi_selection);u=b.getElementById(t.settings.browse_button);if(u){v=d.getPos(u,b.getElementById(t.settings.container));w=d.getSize(u);d.extend(b.getElementById(t.id+"_flash_container").style,{top:v.y+"px",left:v.x+"px",width:w.w+"px",height:w.h+"px"})}});k.bind("Destroy",function(t){var u;d.removeAllEvents(b.body,t.id);delete g[t.id];delete a[t.id];u=b.getElementById(t.id+"_flash_container");if(u){h.removeChild(u)}});p({success:true})})}})})(window,document,plupload);(function(a){a.runtimes.BrowserPlus=a.addRuntime("browserplus",{getFeatures:function(){return{dragdrop:true,jpgresize:true,pngresize:true,chunks:true,progress:true,multipart:true}},init:function(g,j){var e=window.BrowserPlus,h={},d=g.settings,c=d.resize;function f(o){var n,m,k=[],l,p;for(m=0;m<o.length;m++){l=o[m];p=a.guid();h[p]=l;k.push(new a.File(p,l.name,l.size))}if(m){g.trigger("FilesAdded",k)}}function b(){g.bind("PostInit",function(){var n,l=d.drop_element,p=g.id+"_droptarget",k=document.getElementById(l),m;function q(s,r){e.DragAndDrop.AddDropTarget({id:s},function(t){e.DragAndDrop.AttachCallbacks({id:s,hover:function(u){if(!u&&r){r()}},drop:function(u){if(r){r()}f(u)}},function(){})})}function o(){document.getElementById(p).style.top="-1000px"}if(k){if(document.attachEvent&&(/MSIE/gi).test(navigator.userAgent)){n=document.createElement("div");n.setAttribute("id",p);a.extend(n.style,{position:"absolute",top:"-1000px",background:"red",filter:"alpha(opacity=0)",opacity:0});document.body.appendChild(n);a.addEvent(k,"dragenter",function(s){var r,t;r=document.getElementById(l);t=a.getPos(r);a.extend(document.getElementById(p).style,{top:t.y+"px",left:t.x+"px",width:r.offsetWidth+"px",height:r.offsetHeight+"px"})});q(p,o)}else{q(l)}}a.addEvent(document.getElementById(d.browse_button),"click",function(w){var u=[],s,r,v=d.filters,t;w.preventDefault();no_type_restriction:for(s=0;s<v.length;s++){t=v[s].extensions.split(",");for(r=0;r<t.length;r++){if(t[r]==="*"){u=[];break no_type_restriction}u.push(a.mimeTypes[t[r]])}}e.FileBrowse.OpenBrowseDialog({mimeTypes:u},function(x){if(x.success){f(x.value)}})});k=n=null});g.bind("UploadFile",function(n,k){var m=h[k.id],s={},l=n.settings.chunk_size,o,p=[];function r(t,v){var u;if(k.status==a.FAILED){return}s.name=k.target_name||k.name;if(l){s.chunk=""+t;s.chunks=""+v}u=p.shift();e.Uploader.upload({url:n.settings.url,files:{file:u},cookies:document.cookies,postvars:a.extend(s,n.settings.multipart_params),progressCallback:function(y){var x,w=0;o[t]=parseInt(y.filePercent*u.size/100,10);for(x=0;x<o.length;x++){w+=o[x]}k.loaded=w;n.trigger("UploadProgress",k)}},function(x){var w,y;if(x.success){w=x.value.statusCode;if(l){n.trigger("ChunkUploaded",k,{chunk:t,chunks:v,response:x.value.body,status:w})}if(p.length>0){r(++t,v)}else{k.status=a.DONE;n.trigger("FileUploaded",k,{response:x.value.body,status:w});if(w>=400){n.trigger("Error",{code:a.HTTP_ERROR,message:a.translate("HTTP Error."),file:k,status:w})}}}else{n.trigger("Error",{code:a.GENERIC_ERROR,message:a.translate("Generic Error."),file:k,details:x.error})}})}function q(t){k.size=t.size;if(l){e.FileAccess.chunk({file:t,chunkSize:l},function(w){if(w.success){var x=w.value,u=x.length;o=Array(u);for(var v=0;v<u;v++){o[v]=0;p.push(x[v])}r(0,u)}})}else{o=Array(1);p.push(t);r(0,1)}}if(c&&/\.(png|jpg|jpeg)$/i.test(k.name)){BrowserPlus.ImageAlter.transform({file:m,quality:c.quality||90,actions:[{scale:{maxwidth:c.width,maxheight:c.height}}]},function(t){if(t.success){q(t.value.file)}})}else{q(m)}});j({success:true})}if(e){e.init(function(l){var k=[{service:"Uploader",version:"3"},{service:"DragAndDrop",version:"1"},{service:"FileBrowse",version:"1"},{service:"FileAccess",version:"2"}];if(c){k.push({service:"ImageAlter",version:"4"})}if(l.success){e.require({services:k},function(m){if(m.success){b()}else{j()}})}else{j()}})}else{j()}}})})(plupload);(function(h,k,j,e){var c={},g;function m(o,p){var n;if("FileReader" in h){n=new FileReader();n.readAsDataURL(o);n.onload=function(){p(n.result)}}else{return p(o.getAsDataURL())}}function l(o,p){var n;if("FileReader" in h){n=new FileReader();n.readAsBinaryString(o);n.onload=function(){p(n.result)}}else{return p(o.getAsBinary())}}function d(r,p,n,v){var q,o,u,s,t=this;m(c[r.id],function(w){q=k.createElement("canvas");q.style.display="none";k.body.appendChild(q);o=q.getContext("2d");u=new Image();u.onerror=u.onabort=function(){v({success:false})};u.onload=function(){var B,x,z,y,A;if(!p.width){p.width=u.width}if(!p.height){p.height=u.height}s=Math.min(p.width/u.width,p.height/u.height);if(s<1||(s===1&&n==="image/jpeg")){B=Math.round(u.width*s);x=Math.round(u.height*s);q.width=B;q.height=x;o.drawImage(u,0,0,B,x);if(n==="image/jpeg"){y=new f(atob(w.substring(w.indexOf("base64,")+7)));if(y.headers&&y.headers.length){A=new a();if(A.init(y.get("exif")[0])){A.setExif("PixelXDimension",B);A.setExif("PixelYDimension",x);y.set("exif",A.getBinary());if(t.hasEventListener("ExifData")){t.trigger("ExifData",r,A.EXIF())}if(t.hasEventListener("GpsData")){t.trigger("GpsData",r,A.GPS())}}}if(p.quality){try{w=q.toDataURL(n,p.quality/100)}catch(C){w=q.toDataURL(n)}}}else{w=q.toDataURL(n)}w=w.substring(w.indexOf("base64,")+7);w=atob(w);if(y&&y.headers&&y.headers.length){w=y.restore(w);y.purge()}q.parentNode.removeChild(q);v({success:true,data:w})}else{v({success:false})}};u.src=w})}j.runtimes.Html5=j.addRuntime("html5",{getFeatures:function(){var t,o,s,r,q,n,p;p=(function(){var y=navigator,x=y.userAgent,z=y.vendor,v,u,w;v=/WebKit/.test(x);w=v&&z.indexOf("Apple")!==-1;u=h.opera&&h.opera.buildNumber;return{ie:!v&&!u&&(/MSIE/gi).test(x)&&(/Explorer/gi).test(y.appName),webkit:v,gecko:!v&&/Gecko/.test(x),safari:w,safariwin:w&&navigator.platform.indexOf("Win")!==-1,opera:!!u}}());o=s=q=n=false;if(h.XMLHttpRequest){t=new XMLHttpRequest();s=!!t.upload;o=!!(t.sendAsBinary||t.upload)}if(o){r=!!(t.sendAsBinary||(h.Uint8Array&&h.ArrayBuffer));q=!!(File&&(File.prototype.getAsDataURL||h.FileReader)&&r);n=!!(File&&(File.prototype.mozSlice||File.prototype.webkitSlice||File.prototype.slice))}g=p.safariwin;return{html5:o,dragdrop:(function(){var u=k.createElement("div");return("draggable" in u)||("ondragstart" in u&&"ondrop" in u)}()),jpgresize:q,pngresize:q,multipart:q||!!h.FileReader||!!h.FormData,canSendBinary:r,cantSendBlobInFormData:!!(p.gecko&&h.FormData&&h.FileReader&&!FileReader.prototype.readAsArrayBuffer),progress:s,chunks:n,triggerDialog:(p.gecko&&h.FormData||p.webkit)}},init:function(p,q){var n;function o(v){var t,s,u=[],w,r={};for(s=0;s<v.length;s++){t=v[s];if(r[t.name]){continue}r[t.name]=true;w=j.guid();c[w]=t;u.push(new j.File(w,t.fileName||t.name,t.fileSize||t.size))}if(u.length){p.trigger("FilesAdded",u)}}n=this.getFeatures();if(!n.html5){q({success:false});return}p.bind("Init",function(v){var F,E,B=[],u,C,s=v.settings.filters,t,A,r=k.body,D;F=k.createElement("div");F.id=v.id+"_html5_container";j.extend(F.style,{position:"absolute",background:p.settings.shim_bgcolor||"transparent",width:"100px",height:"100px",overflow:"hidden",zIndex:99999,opacity:p.settings.shim_bgcolor?"":0});F.className="plupload html5";if(p.settings.container){r=k.getElementById(p.settings.container);if(j.getStyle(r,"position")==="static"){r.style.position="relative"}}r.appendChild(F);no_type_restriction:for(u=0;u<s.length;u++){t=s[u].extensions.split(/,/);for(C=0;C<t.length;C++){if(t[C]==="*"){B=[];break no_type_restriction}A=j.mimeTypes[t[C]];if(A){B.push(A)}}}F.innerHTML='<input id="'+p.id+'_html5" style="font-size:999px" type="file" accept="'+B.join(",")+'" '+(p.settings.multi_selection?'multiple="multiple"':"")+" />";F.scrollTop=100;D=k.getElementById(p.id+"_html5");if(v.features.triggerDialog){j.extend(D.style,{position:"absolute",width:"100%",height:"100%"})}else{j.extend(D.style,{cssFloat:"right",styleFloat:"right"})}D.onchange=function(){o(this.files);this.value=""};E=k.getElementById(v.settings.browse_button);if(E){var x=v.settings.browse_button_hover,z=v.settings.browse_button_active,w=v.features.triggerDialog?E:F;if(x){j.addEvent(w,"mouseover",function(){j.addClass(E,x)},v.id);j.addEvent(w,"mouseout",function(){j.removeClass(E,x)},v.id)}if(z){j.addEvent(w,"mousedown",function(){j.addClass(E,z)},v.id);j.addEvent(k.body,"mouseup",function(){j.removeClass(E,z)},v.id)}if(v.features.triggerDialog){j.addEvent(E,"click",function(y){k.getElementById(v.id+"_html5").click();y.preventDefault()},v.id)}}});p.bind("PostInit",function(){var r=k.getElementById(p.settings.drop_element);if(r){if(g){j.addEvent(r,"dragenter",function(v){var u,s,t;u=k.getElementById(p.id+"_drop");if(!u){u=k.createElement("input");u.setAttribute("type","file");u.setAttribute("id",p.id+"_drop");u.setAttribute("multiple","multiple");j.addEvent(u,"change",function(){o(this.files);j.removeEvent(u,"change",p.id);u.parentNode.removeChild(u)},p.id);r.appendChild(u)}s=j.getPos(r,k.getElementById(p.settings.container));t=j.getSize(r);if(j.getStyle(r,"position")==="static"){j.extend(r.style,{position:"relative"})}j.extend(u.style,{position:"absolute",display:"block",top:0,left:0,width:t.w+"px",height:t.h+"px",opacity:0})},p.id);return}j.addEvent(r,"dragover",function(s){s.preventDefault()},p.id);j.addEvent(r,"drop",function(t){var s=t.dataTransfer;if(s&&s.files){o(s.files)}t.preventDefault()},p.id)}});p.bind("Refresh",function(r){var s,t,u,w,v;s=k.getElementById(p.settings.browse_button);if(s){t=j.getPos(s,k.getElementById(r.settings.container));u=j.getSize(s);w=k.getElementById(p.id+"_html5_container");j.extend(w.style,{top:t.y+"px",left:t.x+"px",width:u.w+"px",height:u.h+"px"});if(p.features.triggerDialog){if(j.getStyle(s,"position")==="static"){j.extend(s.style,{position:"relative"})}v=parseInt(j.getStyle(s,"z-index"),10);if(isNaN(v)){v=0}j.extend(s.style,{zIndex:v});j.extend(w.style,{zIndex:v-1})}}});p.bind("UploadFile",function(r,t){var u=r.settings,x,s;function w(z,C,y){var A;if(File.prototype.slice){try{z.slice();return z.slice(C,y)}catch(B){return z.slice(C,y-C)}}else{if(A=File.prototype.webkitSlice||File.prototype.mozSlice){return A.call(z,C,y)}else{return null}}}function v(z){var C=0,B=0,y=("FileReader" in h)?new FileReader:null,D=typeof(z)==="string";function A(){var I,M,K,L,H,J,F,E=r.settings.url;function G(W){var T=0,U=new XMLHttpRequest,X=U.upload,N="----pluploadboundary"+j.guid(),O,P="--",V="\r\n",R="";if(X){X.onprogress=function(Y){t.loaded=Math.min(t.size,B+Y.loaded-T);r.trigger("UploadProgress",t)}}U.onreadystatechange=function(){var Y,aa;if(U.readyState==4){try{Y=U.status}catch(Z){Y=0}if(Y>=400){r.trigger("Error",{code:j.HTTP_ERROR,message:j.translate("HTTP Error."),file:t,status:Y})}else{if(K){aa={chunk:C,chunks:K,response:U.responseText,status:Y};r.trigger("ChunkUploaded",t,aa);B+=J;if(aa.cancelled){t.status=j.FAILED;return}t.loaded=Math.min(t.size,(C+1)*H)}else{t.loaded=t.size}r.trigger("UploadProgress",t);W=I=O=R=null;if(!K||++C>=K){t.status=j.DONE;r.trigger("FileUploaded",t,{response:U.responseText,status:Y})}else{A()}}U=null}};if(r.settings.multipart&&n.multipart){L.name=t.target_name||t.name;U.open("post",E,true);j.each(r.settings.headers,function(Z,Y){U.setRequestHeader(Y,Z)});if(!D&&!!h.FormData){O=new FormData();j.each(j.extend(L,r.settings.multipart_params),function(Z,Y){O.append(Y,Z)});O.append(r.settings.file_data_name,W);U.send(O);return}if(D){U.setRequestHeader("Content-Type","multipart/form-data; boundary="+N);j.each(j.extend(L,r.settings.multipart_params),function(Z,Y){R+=P+N+V+'Content-Disposition: form-data; name="'+Y+'"'+V+V;R+=unescape(encodeURIComponent(Z))+V});F=j.mimeTypes[t.name.replace(/^.+\.([^.]+)/,"$1").toLowerCase()]||"application/octet-stream";R+=P+N+V+'Content-Disposition: form-data; name="'+r.settings.file_data_name+'"; filename="'+unescape(encodeURIComponent(t.name))+'"'+V+"Content-Type: "+F+V+V+W+V+P+N+P+V;T=R.length-W.length;W=R;if(U.sendAsBinary){U.sendAsBinary(W)}else{if(n.canSendBinary){var S=new Uint8Array(W.length);for(var Q=0;Q<W.length;Q++){S[Q]=(W.charCodeAt(Q)&255)}U.send(S.buffer)}}return}}E=j.buildUrl(r.settings.url,j.extend(L,r.settings.multipart_params));U.open("post",E,true);U.setRequestHeader("Content-Type","application/octet-stream");j.each(r.settings.headers,function(Z,Y){U.setRequestHeader(Y,Z)});U.send(W)}if(t.status==j.DONE||t.status==j.FAILED||r.state==j.STOPPED){return}L={name:t.target_name||t.name};if(u.chunk_size&&t.size>u.chunk_size&&(n.chunks||typeof(z)=="string")){H=u.chunk_size;K=Math.ceil(t.size/H);J=Math.min(H,t.size-(C*H));if(typeof(z)=="string"){I=z.substring(C*H,C*H+J)}else{I=w(z,C*H,C*H+J)}L.chunk=C;L.chunks=K}else{J=t.size;I=z}if(y&&n.cantSendBlobInFormData&&n.chunks&&r.settings.chunk_size){y.onload=function(){D=true;G(y.result)};y.readAsBinaryString(I)}else{G(I)}}A()}x=c[t.id];if(n.jpgresize&&r.settings.resize&&/\.(png|jpg|jpeg)$/i.test(t.name)){d.call(r,t,r.settings.resize,/\.png$/i.test(t.name)?"image/png":"image/jpeg",function(y){if(y.success){t.size=y.data.length;v(y.data)}else{v(x)}})}else{if(!n.chunks&&n.jpgresize){l(x,v)}else{v(x)}}});p.bind("Destroy",function(r){var t,u,s=k.body,v={inputContainer:r.id+"_html5_container",inputFile:r.id+"_html5",browseButton:r.settings.browse_button,dropElm:r.settings.drop_element};for(t in v){u=k.getElementById(v[t]);if(u){j.removeAllEvents(u,r.id)}}j.removeAllEvents(k.body,r.id);if(r.settings.container){s=k.getElementById(r.settings.container)}s.removeChild(k.getElementById(v.inputContainer))});q({success:true})}});function b(){var q=false,o;function r(t,v){var s=q?0:-8*(v-1),w=0,u;for(u=0;u<v;u++){w|=(o.charCodeAt(t+u)<<Math.abs(s+u*8))}return w}function n(u,s,t){var t=arguments.length===3?t:o.length-s-1;o=o.substr(0,s)+u+o.substr(t+s)}function p(t,u,w){var x="",s=q?0:-8*(w-1),v;for(v=0;v<w;v++){x+=String.fromCharCode((u>>Math.abs(s+v*8))&255)}n(x,t,w)}return{II:function(s){if(s===e){return q}else{q=s}},init:function(s){q=false;o=s},SEGMENT:function(s,u,t){switch(arguments.length){case 1:return o.substr(s,o.length-s-1);case 2:return o.substr(s,u);case 3:n(t,s,u);break;default:return o}},BYTE:function(s){return r(s,1)},SHORT:function(s){return r(s,2)},LONG:function(s,t){if(t===e){return r(s,4)}else{p(s,t,4)}},SLONG:function(s){var t=r(s,4);return(t>2147483647?t-4294967296:t)},STRING:function(s,t){var u="";for(t+=s;s<t;s++){u+=String.fromCharCode(r(s,1))}return u}}}function f(s){var u={65505:{app:"EXIF",name:"APP1",signature:"Exif\0"},65506:{app:"ICC",name:"APP2",signature:"ICC_PROFILE\0"},65517:{app:"IPTC",name:"APP13",signature:"Photoshop 3.0\0"}},t=[],r,n,p=e,q=0,o;r=new b();r.init(s);if(r.SHORT(0)!==65496){return}n=2;o=Math.min(1048576,s.length);while(n<=o){p=r.SHORT(n);if(p>=65488&&p<=65495){n+=2;continue}if(p===65498||p===65497){break}q=r.SHORT(n+2)+2;if(u[p]&&r.STRING(n+4,u[p].signature.length)===u[p].signature){t.push({hex:p,app:u[p].app.toUpperCase(),name:u[p].name.toUpperCase(),start:n,length:q,segment:r.SEGMENT(n,q)})}n+=q}r.init(null);return{headers:t,restore:function(y){r.init(y);var w=new f(y);if(!w.headers){return false}for(var x=w.headers.length;x>0;x--){var z=w.headers[x-1];r.SEGMENT(z.start,z.length,"")}w.purge();n=r.SHORT(2)==65504?4+r.SHORT(4):2;for(var x=0,v=t.length;x<v;x++){r.SEGMENT(n,0,t[x].segment);n+=t[x].length}return r.SEGMENT()},get:function(x){var y=[];for(var w=0,v=t.length;w<v;w++){if(t[w].app===x.toUpperCase()){y.push(t[w].segment)}}return y},set:function(y,x){var z=[];if(typeof(x)==="string"){z.push(x)}else{z=x}for(var w=ii=0,v=t.length;w<v;w++){if(t[w].app===y.toUpperCase()){t[w].segment=z[ii];t[w].length=z[ii].length;ii++}if(ii>=z.length){break}}},purge:function(){t=[];r.init(null)}}}function a(){var q,n,o={},t;q=new b();n={tiff:{274:"Orientation",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer"},exif:{36864:"ExifVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",36867:"DateTimeOriginal",33434:"ExposureTime",33437:"FNumber",34855:"ISOSpeedRatings",37377:"ShutterSpeedValue",37378:"ApertureValue",37383:"MeteringMode",37384:"LightSource",37385:"Flash",41986:"ExposureMode",41987:"WhiteBalance",41990:"SceneCaptureType",41988:"DigitalZoomRatio",41992:"Contrast",41993:"Saturation",41994:"Sharpness"},gps:{0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude"}};t={ColorSpace:{1:"sRGB",0:"Uncalibrated"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{1:"Daylight",2:"Fliorescent",3:"Tungsten",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 -5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire.",1:"Flash fired.",5:"Strobe return light not detected.",7:"Strobe return light detected.",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},ExposureMode:{0:"Auto exposure",1:"Manual exposure",2:"Auto bracket"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},GPSLatitudeRef:{N:"North latitude",S:"South latitude"},GPSLongitudeRef:{E:"East longitude",W:"West longitude"}};function p(u,C){var w=q.SHORT(u),z,F,G,B,A,v,x,D,E=[],y={};for(z=0;z<w;z++){x=v=u+12*z+2;G=C[q.SHORT(x)];if(G===e){continue}B=q.SHORT(x+=2);A=q.LONG(x+=2);x+=4;E=[];switch(B){case 1:case 7:if(A>4){x=q.LONG(x)+o.tiffHeader}for(F=0;F<A;F++){E[F]=q.BYTE(x+F)}break;case 2:if(A>4){x=q.LONG(x)+o.tiffHeader}y[G]=q.STRING(x,A-1);continue;case 3:if(A>2){x=q.LONG(x)+o.tiffHeader}for(F=0;F<A;F++){E[F]=q.SHORT(x+F*2)}break;case 4:if(A>1){x=q.LONG(x)+o.tiffHeader}for(F=0;F<A;F++){E[F]=q.LONG(x+F*4)}break;case 5:x=q.LONG(x)+o.tiffHeader;for(F=0;F<A;F++){E[F]=q.LONG(x+F*4)/q.LONG(x+F*4+4)}break;case 9:x=q.LONG(x)+o.tiffHeader;for(F=0;F<A;F++){E[F]=q.SLONG(x+F*4)}break;case 10:x=q.LONG(x)+o.tiffHeader;for(F=0;F<A;F++){E[F]=q.SLONG(x+F*4)/q.SLONG(x+F*4+4)}break;default:continue}D=(A==1?E[0]:E);if(t.hasOwnProperty(G)&&typeof D!="object"){y[G]=t[G][D]}else{y[G]=D}}return y}function s(){var v=e,u=o.tiffHeader;q.II(q.SHORT(u)==18761);if(q.SHORT(u+=2)!==42){return false}o.IFD0=o.tiffHeader+q.LONG(u+=2);v=p(o.IFD0,n.tiff);o.exifIFD=("ExifIFDPointer" in v?o.tiffHeader+v.ExifIFDPointer:e);o.gpsIFD=("GPSInfoIFDPointer" in v?o.tiffHeader+v.GPSInfoIFDPointer:e);return true}function r(w,u,z){var B,y,x,A=0;if(typeof(u)==="string"){var v=n[w.toLowerCase()];for(hex in v){if(v[hex]===u){u=hex;break}}}B=o[w.toLowerCase()+"IFD"];y=q.SHORT(B);for(i=0;i<y;i++){x=B+12*i+2;if(q.SHORT(x)==u){A=x+8;break}}if(!A){return false}q.LONG(A,z);return true}return{init:function(u){o={tiffHeader:10};if(u===e||!u.length){return false}q.init(u);if(q.SHORT(0)===65505&&q.STRING(4,5).toUpperCase()==="EXIF\0"){return s()}return false},EXIF:function(){var u;u=p(o.exifIFD,n.exif);if(u.ExifVersion){u.ExifVersion=String.fromCharCode(u.ExifVersion[0],u.ExifVersion[1],u.ExifVersion[2],u.ExifVersion[3])}return u},GPS:function(){var u;u=p(o.gpsIFD,n.gps);if(u.GPSVersionID){u.GPSVersionID=u.GPSVersionID.join(".")}return u},setExif:function(u,v){if(u!=="PixelXDimension"&&u!=="PixelYDimension"){return false}return r("exif",u,v)},getBinary:function(){return q.SEGMENT()}}}})(window,document,plupload);(function(d,a,b,c){function e(f){return a.getElementById(f)}b.runtimes.Html4=b.addRuntime("html4",{getFeatures:function(){var f=(function(){var l=navigator,k=l.userAgent,m=l.vendor,h,g,j;h=/WebKit/.test(k);j=h&&m.indexOf("Apple")!==-1;g=d.opera&&d.opera.buildNumber;return{ie:!h&&!g&&(/MSIE/gi).test(k)&&(/Explorer/gi).test(l.appName),webkit:h,gecko:!h&&/Gecko/.test(k),safari:j,safariwin:j&&navigator.platform.indexOf("Win")!==-1,opera:!!g}}());return{multipart:true,triggerDialog:(f.gecko&&d.FormData||f.webkit)}},init:function(f,g){f.bind("Init",function(p){var j=a.body,n,h="javascript",k,x,q,z=[],r=/MSIE/.test(navigator.userAgent),t=[],m=p.settings.filters,o,l,s,w;no_type_restriction:for(o=0;o<m.length;o++){l=m[o].extensions.split(/,/);for(w=0;w<l.length;w++){if(l[w]==="*"){t=[];break no_type_restriction}s=b.mimeTypes[l[w]];if(s){t.push(s)}}}t=t.join(",");function v(){var C,A,y,B;q=b.guid();z.push(q);C=a.createElement("form");C.setAttribute("id","form_"+q);C.setAttribute("method","post");C.setAttribute("enctype","multipart/form-data");C.setAttribute("encoding","multipart/form-data");C.setAttribute("target",p.id+"_iframe");C.style.position="absolute";A=a.createElement("input");A.setAttribute("id","input_"+q);A.setAttribute("type","file");A.setAttribute("accept",t);A.setAttribute("size",1);B=e(p.settings.browse_button);if(p.features.triggerDialog&&B){b.addEvent(e(p.settings.browse_button),"click",function(D){A.click();D.preventDefault()},p.id)}b.extend(A.style,{width:"100%",height:"100%",opacity:0,fontSize:"999px"});b.extend(C.style,{overflow:"hidden"});y=p.settings.shim_bgcolor;if(y){C.style.background=y}if(r){b.extend(A.style,{filter:"alpha(opacity=0)"})}b.addEvent(A,"change",function(G){var E=G.target,D,F=[],H;if(E.value){e("form_"+q).style.top=-1048575+"px";D=E.value.replace(/\\/g,"/");D=D.substring(D.length,D.lastIndexOf("/")+1);F.push(new b.File(q,D));if(!p.features.triggerDialog){b.removeAllEvents(C,p.id)}else{b.removeEvent(B,"click",p.id)}b.removeEvent(A,"change",p.id);v();if(F.length){f.trigger("FilesAdded",F)}}},p.id);C.appendChild(A);j.appendChild(C);p.refresh()}function u(){var y=a.createElement("div");y.innerHTML='<iframe id="'+p.id+'_iframe" name="'+p.id+'_iframe" src="'+h+':""" style="display:none"></iframe>';n=y.firstChild;j.appendChild(n);b.addEvent(n,"load",function(D){var E=D.target,C,A;if(!k){return}try{C=E.contentWindow.document||E.contentDocument||d.frames[E.id].document}catch(B){p.trigger("Error",{code:b.SECURITY_ERROR,message:b.translate("Security error."),file:k});return}A=C.documentElement.innerText||C.documentElement.textContent;if(A){k.status=b.DONE;k.loaded=1025;k.percent=100;p.trigger("UploadProgress",k);p.trigger("FileUploaded",k,{response:A})}},p.id)}if(p.settings.container){j=e(p.settings.container);if(b.getStyle(j,"position")==="static"){j.style.position="relative"}}p.bind("UploadFile",function(y,B){var C,A;if(B.status==b.DONE||B.status==b.FAILED||y.state==b.STOPPED){return}C=e("form_"+B.id);A=e("input_"+B.id);A.setAttribute("name",y.settings.file_data_name);C.setAttribute("action",y.settings.url);b.each(b.extend({name:B.target_name||B.name},y.settings.multipart_params),function(F,D){var E=a.createElement("input");b.extend(E,{type:"hidden",name:D,value:F});C.insertBefore(E,C.firstChild)});k=B;e("form_"+q).style.top=-1048575+"px";C.submit();C.parentNode.removeChild(C)});p.bind("FileUploaded",function(y){y.refresh()});p.bind("StateChanged",function(y){if(y.state==b.STARTED){u()}if(y.state==b.STOPPED){d.setTimeout(function(){b.removeEvent(n,"load",y.id);n.parentNode.removeChild(n)},0)}});p.bind("Refresh",function(A){var G,B,C,D,y,H,I,F,E;G=e(A.settings.browse_button);if(G){y=b.getPos(G,e(A.settings.container));H=b.getSize(G);I=e("form_"+q);F=e("input_"+q);b.extend(I.style,{top:y.y+"px",left:y.x+"px",width:H.w+"px",height:H.h+"px"});if(A.features.triggerDialog){if(b.getStyle(G,"position")==="static"){b.extend(G.style,{position:"relative"})}E=parseInt(G.style.zIndex,10);if(isNaN(E)){E=0}b.extend(G.style,{zIndex:E});b.extend(I.style,{zIndex:E-1})}C=A.settings.browse_button_hover;D=A.settings.browse_button_active;B=A.features.triggerDialog?G:I;if(C){b.addEvent(B,"mouseover",function(){b.addClass(G,C)},A.id);b.addEvent(B,"mouseout",function(){b.removeClass(G,C)},A.id)}if(D){b.addEvent(B,"mousedown",function(){b.addClass(G,D)},A.id);b.addEvent(a.body,"mouseup",function(){b.removeClass(G,D)},A.id)}}});f.bind("FilesRemoved",function(y,B){var A,C;for(A=0;A<B.length;A++){C=e("form_"+B[A].id);if(C){C.parentNode.removeChild(C)}}});f.bind("Destroy",function(y){var A,B,C,D={inputContainer:"form_"+q,inputFile:"input_"+q,browseButton:y.settings.browse_button};for(A in D){B=e(D[A]);if(B){b.removeAllEvents(B,y.id)}}b.removeAllEvents(a.body,y.id);b.each(z,function(F,E){C=e("form_"+F);if(C){j.removeChild(C)}})});v()});g({success:true})}})})(window,document,plupload);
|
static/js/plupload/plupload.silverlight.xap
ADDED
Binary file
|
static/js/plupload/wplupload.js
ADDED
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
(function(window, $, undefined) {
|
2 |
+
|
3 |
+
var _parent = window.dialogArguments || opener || parent || top;
|
4 |
+
|
5 |
+
$.fn.wplupload = function($options) {
|
6 |
+
var $up, $defaults = {
|
7 |
+
runtimes : 'gears,browserplus,html5,flash,silverlight,html4',
|
8 |
+
browse_button_hover: 'hover',
|
9 |
+
browse_button_active: 'active'
|
10 |
+
};
|
11 |
+
|
12 |
+
$options = $.extend({}, $defaults, $options);
|
13 |
+
|
14 |
+
return this.each(function() {
|
15 |
+
var $this = $(this);
|
16 |
+
|
17 |
+
$up = new plupload.Uploader($options);
|
18 |
+
|
19 |
+
|
20 |
+
/*$up.bind('Init', function(up) {
|
21 |
+
var dropElm = $('#' + up.settings.drop_element);
|
22 |
+
if (dropElm.length && up.features.dragdrop) {
|
23 |
+
dropElm.bind('dragenter', function() {
|
24 |
+
$(this).css('border', '3px dashed #cccccc');
|
25 |
+
});
|
26 |
+
dropElm.bind('dragout drop', function() {
|
27 |
+
$(this).css('border', 'none');
|
28 |
+
});
|
29 |
+
}
|
30 |
+
});*/
|
31 |
+
|
32 |
+
$up.bind('FilesAdded', function(up, files) {
|
33 |
+
$.each(files, function(i, file) {
|
34 |
+
// Create a progress bar containing the filename
|
35 |
+
$('#basic').find('.submit-buttons').hide();
|
36 |
+
$('#progress').css({'visibility':'visible'});
|
37 |
+
})
|
38 |
+
});
|
39 |
+
|
40 |
+
$up.init();
|
41 |
+
|
42 |
+
$up.bind('Error', function(up, err) {
|
43 |
+
$('#upload_process').html(err.message);
|
44 |
+
});
|
45 |
+
|
46 |
+
$up.bind('FilesAdded', function(up, files) {
|
47 |
+
// Disable submit and enable cancel
|
48 |
+
|
49 |
+
$('#cancel-upload').removeAttr('disabled');
|
50 |
+
|
51 |
+
$up.start();
|
52 |
+
});
|
53 |
+
|
54 |
+
$up.bind('UploadFile', function(up, file, r) {
|
55 |
+
|
56 |
+
});
|
57 |
+
|
58 |
+
$up.bind('UploadProgress', function(up, file) {
|
59 |
+
// Lengthen the progress bar
|
60 |
+
$('#progressbar').html('Uploading data feed ... ' + file.percent + '%');
|
61 |
+
$('#upload_process').progressbar({value:file.percent});
|
62 |
+
|
63 |
+
});
|
64 |
+
|
65 |
+
|
66 |
+
$up.bind('FileUploaded', function(up, file, r) {
|
67 |
+
var fetch = typeof(shortform) == 'undefined' ? 1 : 2;
|
68 |
+
|
69 |
+
r = _parseJSON(r.response);
|
70 |
+
|
71 |
+
$('#filepath').val(r.name);
|
72 |
+
|
73 |
+
$('#progressbar').html('Upload Complete - ' + file.name + ' (' + ( (file.size / (1024*1024) >= 1) ? (file.size / (1024*1024)).toFixed(2) + 'mb' : (file.size / (1024)).toFixed(2) + 'kb') + ')');
|
74 |
+
|
75 |
+
$('#basic').find('.submit-buttons').show();
|
76 |
+
|
77 |
+
if (r.OK) {
|
78 |
+
|
79 |
+
}
|
80 |
+
});
|
81 |
+
|
82 |
+
$up.bind('UploadComplete', function(up) {
|
83 |
+
$('#cancel-upload').attr('disabled', 'disabled');
|
84 |
+
});
|
85 |
+
|
86 |
+
$('#cancel-upload').click(function() {
|
87 |
+
var i, file;
|
88 |
+
|
89 |
+
$up.stop();
|
90 |
+
|
91 |
+
i = $up.files.length;
|
92 |
+
for (i = $up.files.length - 1; i >= 0; i--) {
|
93 |
+
file = $up.files[i];
|
94 |
+
if ($.inArray(file.status, [plupload.QUEUED, plupload.UPLOADING]) !== -1) {
|
95 |
+
$up.removeFile($up.getFile(file.id));
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
$('#cancel-upload').attr('disabled', 'disabled');
|
100 |
+
|
101 |
+
});
|
102 |
+
|
103 |
+
});
|
104 |
+
};
|
105 |
+
|
106 |
+
function _parseJSON(r) {
|
107 |
+
var obj;
|
108 |
+
try {
|
109 |
+
obj = $.parseJSON(r);
|
110 |
+
} catch (e) {
|
111 |
+
obj = { OK : 0 };
|
112 |
+
}
|
113 |
+
return obj;
|
114 |
+
}
|
115 |
+
|
116 |
+
}(window, jQuery));
|
static/js/pmxi.js
CHANGED
@@ -2,13 +2,6 @@
|
|
2 |
* plugin javascript
|
3 |
*/
|
4 |
(function($){$(function () {
|
5 |
-
|
6 |
-
$('#dismiss').click(function(){
|
7 |
-
|
8 |
-
$(this).parents('div.error:first').slideUp();
|
9 |
-
$.post('admin.php?page=pmxi-admin-settings&action=dismiss', {dismiss: true}, function (data) {
|
10 |
-
|
11 |
-
}, 'html');
|
12 |
-
})
|
13 |
|
14 |
});})(jQuery);
|
2 |
* plugin javascript
|
3 |
*/
|
4 |
(function($){$(function () {
|
5 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
});})(jQuery);
|
views/admin/import/element_after.php
CHANGED
@@ -1,39 +1,58 @@
|
|
1 |
<form class="choose-elements no-enter-submit" method="post">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
<table class="layout">
|
3 |
<tr>
|
4 |
<td class="left">
|
5 |
-
<
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
<?php
|
16 |
-
|
17 |
-
</
|
18 |
-
|
19 |
-
<div class="xml">
|
20 |
-
<?php $this->render_xml_element($dom->documentElement) ?>
|
21 |
-
</div>
|
22 |
</td>
|
23 |
<td class="right">
|
24 |
-
<
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
|
34 |
<input type="hidden" name="is_submitted" value="1" />
|
35 |
<?php wp_nonce_field('choose-elements', '_wpnonce_choose-elements') ?>
|
36 |
-
<input type="submit" class="button-
|
37 |
</p>
|
38 |
</td>
|
39 |
</tr>
|
1 |
<form class="choose-elements no-enter-submit" method="post">
|
2 |
+
<h2><?php _e('Import XML/CSV - Step 2: Select Elements', 'pmxi_plugin') ?></h2>
|
3 |
+
|
4 |
+
<h3><?php _e('<b>Double-click on an element below to select it and its siblings.</b>', 'pmxi_plugin') ?></h3>
|
5 |
+
|
6 |
+
<div class="ajax-console">
|
7 |
+
<?php if ($this->errors->get_error_codes()): ?>
|
8 |
+
<?php $this->error() ?>
|
9 |
+
<?php endif ?>
|
10 |
+
</div>
|
11 |
<table class="layout">
|
12 |
<tr>
|
13 |
<td class="left">
|
14 |
+
<fieldset class="widefat">
|
15 |
+
<legend>Current XML tree</legend>
|
16 |
+
<div class="action_buttons">
|
17 |
+
<a href="javascript:void(0);" id="prev_element" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" style="float:left;">⟨⟨</a>
|
18 |
+
<a href="javascript:void(0);" id="next_element" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" style="float:left; margin-right:15px;">⟩⟩</a>
|
19 |
+
<div style="float:left;">
|
20 |
+
<span style="font-size:18px; padding-top:15px; float:left; margin-right:10px;">Go to: </span><input type="text" id="goto_element" value="1"/>
|
21 |
+
</div>
|
22 |
+
</div>
|
23 |
+
<div class="xml" style="min-height:400px;">
|
24 |
+
<?php //$this->render_xml_element($dom->documentElement) ?>
|
25 |
+
</div>
|
26 |
+
</fieldset>
|
|
|
|
|
|
|
|
|
27 |
</td>
|
28 |
<td class="right">
|
29 |
+
<fieldset class="widefat">
|
30 |
+
<legend>Advanced</legend>
|
31 |
+
<p>Current XPath:</p>
|
32 |
+
<div>
|
33 |
+
<input type="text" name="xpath" value="<?php echo esc_attr($post['xpath']) ?>" style="max-width:none;" />
|
34 |
+
<input type="hidden" id="root_element" name="root_element" value="<?php echo $_SESSION['pmxi_import']['source']['root_element']; ?>"/>
|
35 |
+
<?php
|
36 |
+
if (!empty($elements_cloud)){
|
37 |
+
?>
|
38 |
+
<br/><label>What element are you looking for?</label> <br/>
|
39 |
+
<?php
|
40 |
+
$root_elements = array();
|
41 |
+
foreach ($elements_cloud as $tag => $count)
|
42 |
+
$root_elements[] = '<a href="javascript:void(0);" rel="'. $tag .'" class="change_root_element">' . $tag . '</a>';
|
43 |
+
echo implode(', ', $root_elements);
|
44 |
+
}
|
45 |
+
?>
|
46 |
+
<br/><br/>or <a href="javascript:void(0);" rel="<?php echo esc_attr($post['xpath']) ?>" root="<?php echo $_SESSION['pmxi_import']['source']['root_element']; ?>" id="get_default_xpath">get default xPath</a>
|
47 |
+
</div> <br><br>
|
48 |
+
<a href="http://www.w3schools.com/xpath/default.asp" target='_blank'>XPath Tutorial</a> - For further help, <a href="http://www.wpallimport.com/support" target='_blank'>contact us</a>.
|
49 |
+
</fieldset>
|
50 |
+
<p class="submit-buttons" style="text-align:right;">
|
51 |
+
<a href="<?php echo $this->baseUrl ?>" class="back">Back</a>
|
52 |
|
53 |
<input type="hidden" name="is_submitted" value="1" />
|
54 |
<?php wp_nonce_field('choose-elements', '_wpnonce_choose-elements') ?>
|
55 |
+
<input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Next', 'pmxi_plugin') ?>" />
|
56 |
</p>
|
57 |
</td>
|
58 |
</tr>
|
views/admin/import/evaluate.php
CHANGED
@@ -1,15 +1,20 @@
|
|
1 |
<div class="updated">
|
2 |
-
<p><?php printf(__('
|
3 |
-
<?php if (PMXI_Plugin::getInstance()->getOption('highlight_limit') and $
|
4 |
<p><?php _e('<strong>Note</strong>: Highlighting is turned off since can be very slow on large sets of elements.', 'pmxi_plugin') ?></p>
|
5 |
<?php endif ?>
|
6 |
</div>
|
|
|
|
|
|
|
7 |
<script type="text/javascript">
|
8 |
-
(function($){
|
9 |
var paths = <?php echo json_encode($paths) ?>;
|
10 |
var $xml = $('.xml');
|
|
|
|
|
11 |
for (var i = 0; i < paths.length; i++) {
|
12 |
$xml.find('.xml-element[title="' + paths[i] + '"]').addClass('selected').parents('.xml-element').find('> .xml-content.collapsed').removeClass('collapsed').parent().find('> .xml-expander').html('-');
|
13 |
-
}
|
14 |
})(jQuery);
|
15 |
</script>
|
1 |
<div class="updated">
|
2 |
+
<p><?php printf(__('Current selection matches <span class="matches_count">%s</span> %s.', 'pmxi_plugin'), $node_list_count, _n('element', 'elements', $node_list_count, 'pmxi_plugin')) ?></p>
|
3 |
+
<?php if (PMXI_Plugin::getInstance()->getOption('highlight_limit') and $elements->length > PMXI_Plugin::getInstance()->getOption('highlight_limit')): ?>
|
4 |
<p><?php _e('<strong>Note</strong>: Highlighting is turned off since can be very slow on large sets of elements.', 'pmxi_plugin') ?></p>
|
5 |
<?php endif ?>
|
6 |
</div>
|
7 |
+
<div id="current_xml">
|
8 |
+
<?php $this->render_xml_element($elements->item( ($_POST['show_element'] and !$_SESSION['pmxi_import']['large_file']) ? $_POST['show_element'] - 1 : 0 ), false, '//'); ?>
|
9 |
+
</div>
|
10 |
<script type="text/javascript">
|
11 |
+
(function($){
|
12 |
var paths = <?php echo json_encode($paths) ?>;
|
13 |
var $xml = $('.xml');
|
14 |
+
|
15 |
+
$xml.html($('#current_xml').html()).css({'visibility':'visible'});
|
16 |
for (var i = 0; i < paths.length; i++) {
|
17 |
$xml.find('.xml-element[title="' + paths[i] + '"]').addClass('selected').parents('.xml-element').find('> .xml-content.collapsed').removeClass('collapsed').parent().find('> .xml-expander').html('-');
|
18 |
+
}
|
19 |
})(jQuery);
|
20 |
</script>
|
views/admin/import/index.php
CHANGED
@@ -1,101 +1,122 @@
|
|
1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
<tr>
|
3 |
<td class="left">
|
4 |
-
<h2><?php _e('Import XML/CSV - Step 1: Choose Your File', 'pmxi_plugin')
|
5 |
-
<
|
6 |
|
7 |
<?php if ($this->errors->get_error_codes()): ?>
|
8 |
<?php $this->error() ?>
|
9 |
<?php endif ?>
|
10 |
-
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
<input type="hidden" name="is_submitted" value="1" />
|
13 |
<?php wp_nonce_field('upload-xml', '_wpnonce_upload-xml') ?>
|
14 |
-
|
15 |
<div class="file-type-container">
|
16 |
<h3>
|
17 |
-
<input type="radio" id="type_upload" name="type" value="upload"
|
18 |
-
<label for="type_upload"><?php _e('Upload
|
19 |
</h3>
|
20 |
-
<div class="file-type-options">
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
</div>
|
25 |
<div class="file-type-container">
|
26 |
<h3>
|
27 |
-
<input type="radio" id="type_url" name="type" value="url"
|
28 |
-
<label for="type_url"><?php _e('
|
29 |
</h3>
|
30 |
<div class="file-type-options">
|
31 |
-
<input type="text" class="regular-text" name="url" value="
|
|
|
32 |
</div>
|
33 |
</div>
|
34 |
<div class="file-type-container">
|
35 |
<h3>
|
36 |
-
<input type="radio" id="type_ftp" name="type" value="ftp"
|
37 |
-
<label for="type_ftp"><?php _e('
|
38 |
</h3>
|
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"
|
|
|
43 |
</div>
|
44 |
</div>
|
45 |
<div class="file-type-container">
|
46 |
<h3>
|
47 |
-
<input type="radio" id="type_file" name="type" value="file"
|
48 |
-
<label for="type_file"><?php _e('
|
49 |
</h3>
|
50 |
<div class="file-type-options">
|
51 |
-
<input type="text" id="__FILE_SOURCE" class="regular-text autocomplete" name="file" value="
|
52 |
<?php
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
|
|
59 |
?>
|
60 |
<script type="text/javascript">
|
61 |
__FILE_SOURCE = <?php echo json_encode($local_files) ?>;
|
62 |
</script>
|
63 |
<div class="note"><?php printf(__('Upload files to <strong>%s</strong> and they will appear in this list', 'pmxi_plugin'), PMXI_Plugin::ROOT_DIR . '/upload/') ?></div>
|
|
|
64 |
</div>
|
65 |
</div>
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
<div class="file-type-options">
|
73 |
-
<input type="text" id="__REIMPORT_SOURCE" class="regular-text autocomplete" name="reimport" value="<?php echo esc_attr($post['reimport']) ?>" readonly="readonly" />
|
74 |
-
<?php
|
75 |
-
$reimports = array();
|
76 |
-
foreach ($history as $file) $reimports[] = '#' . $file['id'] . ': ' . $file['name'] . __(' on ', 'pmxi_plugin') . mysql2date('Y/m/d', $file['registered_on']) . ' - ' . preg_replace('%^(\w+://[^:]+:)[^@]+@%', '$1*****@', $file['path']);
|
77 |
-
?>
|
78 |
-
<script type="text/javascript">
|
79 |
-
__REIMPORT_SOURCE = <?php echo json_encode($reimports) ?>;
|
80 |
-
</script>
|
81 |
-
</div>
|
82 |
-
</div>
|
83 |
-
<?php endif ?>
|
84 |
-
|
85 |
-
<div class="file-type-container">
|
86 |
-
<?php if ($imports->count()): ?>
|
87 |
-
<div class="input">
|
88 |
-
<input type="checkbox" id="is_update_previous" name="is_update_previous" class="switcher" disabled="disabled"/>
|
89 |
-
<label for="is_update_previous"><?php _e('Update Previous Import', 'pmxi_plugin') ?></label>
|
90 |
-
</div>
|
91 |
-
<a href="http://www.wpallimport.com/upgrade-to-pro?from=upi" target="_blank">Upgrade to pro to update previous imports.</a>
|
92 |
-
<?php endif ?>
|
93 |
-
<p class="submit-buttons">
|
94 |
-
<input type="hidden" name="is_submitted" value="1" />
|
95 |
-
<?php wp_nonce_field('choose-file', '_wpnonce_choose-file') ?>
|
96 |
-
<input type="submit" class="button-primary" value="<?php _e('Continue', 'pmxi_plugin') ?> >>" />
|
97 |
-
</p>
|
98 |
-
</div>
|
99 |
<br />
|
100 |
<table><tr><td class="note"></td></tr></table>
|
101 |
</form>
|
1 |
+
<?php
|
2 |
+
|
3 |
+
$l10n = array(
|
4 |
+
'queue_limit_exceeded' => 'You have attempted to queue too many files.',
|
5 |
+
'file_exceeds_size_limit' => 'This file exceeds the maximum upload size for this site.',
|
6 |
+
'zero_byte_file' => 'This file is empty. Please try another.',
|
7 |
+
'invalid_filetype' => 'This file type is not allowed. Please try another.',
|
8 |
+
'default_error' => 'An error occurred in the upload. Please try again later.',
|
9 |
+
'missing_upload_url' => 'There was a configuration error. Please contact the server administrator.',
|
10 |
+
'upload_limit_exceeded' => 'You may only upload 1 file.',
|
11 |
+
'http_error' => 'HTTP error.',
|
12 |
+
'upload_failed' => 'Upload failed.',
|
13 |
+
'io_error' => 'IO error.',
|
14 |
+
'security_error' => 'Security error.',
|
15 |
+
'file_cancelled' => 'File canceled.',
|
16 |
+
'upload_stopped' => 'Upload stopped.',
|
17 |
+
'dismiss' => 'Dismiss',
|
18 |
+
'crunching' => 'Crunching…',
|
19 |
+
'deleted' => 'moved to the trash.',
|
20 |
+
'error_uploading' => 'has failed to upload due to an error',
|
21 |
+
'cancel_upload' => 'Cancel upload',
|
22 |
+
'dismiss' => 'Dismiss'
|
23 |
+
);
|
24 |
+
|
25 |
+
?>
|
26 |
+
<script type="text/javascript">
|
27 |
+
var plugin_url = '<?php echo PMXI_ROOT_URL; ?>';
|
28 |
+
var swfuploadL10n = <?php echo json_encode($l10n); ?>;
|
29 |
+
</script>
|
30 |
+
<table class="layout pmxi_step_1">
|
31 |
<tr>
|
32 |
<td class="left">
|
33 |
+
<h2><?php _e('Import XML/CSV - Step 1: Choose Your File', 'pmxi_plugin') ?></h2>
|
34 |
+
<h3><?php _e('Specify the file containing the data to be imported.', 'pmxi_plugin') ?></h3>
|
35 |
|
36 |
<?php if ($this->errors->get_error_codes()): ?>
|
37 |
<?php $this->error() ?>
|
38 |
<?php endif ?>
|
39 |
+
<?php
|
40 |
+
if ( ! $reimported_import->isEmpty()):
|
41 |
+
?>
|
42 |
+
<div id="reimported_notify">
|
43 |
+
<p><?php _e( 'You are importing a new file for: <b>' . $reimported_import->name . '</b>' , 'pmxi_plugin' );?></p>
|
44 |
+
<p><span><?php _e( 'Last imported on ' . date("m-d-Y H:i:s", strtotime($reimported_import->registered_on)) , 'pmxi_plugin' ); ?></span></p>
|
45 |
+
</div>
|
46 |
+
<?php
|
47 |
+
endif;
|
48 |
+
?>
|
49 |
+
<form method="post" class="choose-file no-enter-submit" enctype="multipart/form-data" autocomplete="off">
|
50 |
<input type="hidden" name="is_submitted" value="1" />
|
51 |
<?php wp_nonce_field('upload-xml', '_wpnonce_upload-xml') ?>
|
|
|
52 |
<div class="file-type-container">
|
53 |
<h3>
|
54 |
+
<input type="radio" id="type_upload" name="type" value="upload" checked="checked" />
|
55 |
+
<label for="type_upload"><?php _e('Upload File From Your Computer', 'pmxi_plugin') ?></label>
|
56 |
</h3>
|
57 |
+
<div id="plupload-ui" class="file-type-options">
|
58 |
+
<div>
|
59 |
+
<h3 style="float:left; margin-top:5px;"><label><?php _e( 'Choose file to upload...' ); ?></label></h3>
|
60 |
+
<input type="hidden" name="filepath" value="<?php echo $post['filepath'] ?>" id="filepath"/>
|
61 |
+
<span><input id="select-files" type="button" value="<?php esc_attr_e('Select File'); ?>" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" /></span>
|
62 |
+
<div id="progress" class="progress" <?php if (!empty($post['filepath'])):?>style="visibility: visible;"<?php endif;?>>
|
63 |
+
<div id="upload_process" class="upload_process"></div>
|
64 |
+
<div id="progressbar" class="progressbar"><?php if (!empty($post['filepath'])) _e( 'Import Complete - '.basename($post['filepath']).' 100%', 'pmxi_plugin'); ?></div>
|
65 |
+
</div>
|
66 |
+
</div>
|
67 |
+
</div>
|
68 |
</div>
|
69 |
<div class="file-type-container">
|
70 |
<h3>
|
71 |
+
<input type="radio" id="type_url" name="type" value="url" />
|
72 |
+
<label for="type_url"><?php _e('Download File From URL', 'pmxi_plugin') ?></label>
|
73 |
</h3>
|
74 |
<div class="file-type-options">
|
75 |
+
<input type="text" class="regular-text" name="url" value="" disabled="disabled" />
|
76 |
+
<a href="http://www.wpallimport.com/upgrade-to-pro?from=upi" target="_blank" class="upgrade_link">Upgrade to the paid edition of WP All Import to use this feature.</a>
|
77 |
</div>
|
78 |
</div>
|
79 |
<div class="file-type-container">
|
80 |
<h3>
|
81 |
+
<input type="radio" id="type_ftp" name="type" value="ftp" />
|
82 |
+
<label for="type_ftp"><?php _e('Download File(s) From FTP Server', 'pmxi_plugin') ?></label>
|
83 |
</h3>
|
84 |
<div class="file-type-options">
|
85 |
+
<input type="text" class="regular-text" name="ftp[url]" value="<?php echo esc_attr($post['ftp']['url']) ?>" disabled="disabled" /><br />
|
86 |
+
<input type="text" name="ftp[user]" title="username" style='width: 150px;' disabled="disabled"/><strong>:</strong><input type="password" name="ftp[pass]" title="passowrd" style='width: 150px;' disabled="disabled"/>
|
87 |
+
<div class="note"><?php _e('You may use an asterisk to load multiple files. For example, ftp://example.com/datafeeds/*.xml', 'pmxi_plugin') ?></div>
|
88 |
+
<a href="http://www.wpallimport.com/upgrade-to-pro?from=upi" target="_blank" class="upgrade_link">Upgrade to the paid edition of WP All Import to use this feature.</a>
|
89 |
</div>
|
90 |
</div>
|
91 |
<div class="file-type-container">
|
92 |
<h3>
|
93 |
+
<input type="radio" id="type_file" name="type" value="file" />
|
94 |
+
<label for="type_file"><?php _e('Use Already Uploaded File', 'pmxi_plugin') ?></label>
|
95 |
</h3>
|
96 |
<div class="file-type-options">
|
97 |
+
<input type="text" id="__FILE_SOURCE" class="regular-text autocomplete" name="file" value="" disabled="disabled"/>
|
98 |
<?php
|
99 |
+
$local_files = array_merge(
|
100 |
+
PMXI_Helper::safe_glob(PMXI_Plugin::ROOT_DIR . '/upload/*.xml', PMXI_Helper::GLOB_RECURSE),
|
101 |
+
PMXI_Helper::safe_glob(PMXI_Plugin::ROOT_DIR . '/upload/*.gz', PMXI_Helper::GLOB_RECURSE),
|
102 |
+
PMXI_Helper::safe_glob(PMXI_Plugin::ROOT_DIR . '/upload/*.zip', PMXI_Helper::GLOB_RECURSE),
|
103 |
+
PMXI_Helper::safe_glob(PMXI_Plugin::ROOT_DIR . '/upload/*.csv', PMXI_Helper::GLOB_RECURSE)
|
104 |
+
);
|
105 |
+
sort($local_files);
|
106 |
?>
|
107 |
<script type="text/javascript">
|
108 |
__FILE_SOURCE = <?php echo json_encode($local_files) ?>;
|
109 |
</script>
|
110 |
<div class="note"><?php printf(__('Upload files to <strong>%s</strong> and they will appear in this list', 'pmxi_plugin'), PMXI_Plugin::ROOT_DIR . '/upload/') ?></div>
|
111 |
+
<a href="http://www.wpallimport.com/upgrade-to-pro?from=upi" target="_blank" class="upgrade_link">Upgrade to the paid edition of WP All Import to use this feature.</a>
|
112 |
</div>
|
113 |
</div>
|
114 |
+
<div id="url_upload_status"></div>
|
115 |
+
<p class="submit-buttons">
|
116 |
+
<input type="hidden" name="is_submitted" value="1" />
|
117 |
+
<?php wp_nonce_field('choose-file', '_wpnonce_choose-file') ?>
|
118 |
+
<input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Next', 'pmxi_plugin') ?>" id="advanced_upload"/>
|
119 |
+
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
<br />
|
121 |
<table><tr><td class="note"></td></tr></table>
|
122 |
</form>
|
views/admin/import/options.php
CHANGED
@@ -1,20 +1,21 @@
|
|
1 |
<?php
|
|
|
2 |
if (!function_exists('reverse_taxonomies_html')) {
|
3 |
-
function reverse_taxonomies_html($post_taxonomies, $item_id,
|
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 |
?>
|
@@ -24,382 +25,137 @@
|
|
24 |
}
|
25 |
}
|
26 |
?>
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
</span>
|
37 |
-
|
38 |
-
|
39 |
-
|
|
|
|
|
40 |
</span>
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
<?php endif ?>
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
<tr>
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
<?php
|
66 |
-
|
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>
|
93 |
-
<th><?php _e('Tags', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Enter tags separated by commas.', 'pmxi_plugin') ?>">?</a></th>
|
94 |
-
<td><input type="text" name="tags" class="widefat" value="<?php echo esc_attr($post['tags']) ?>" /></td>
|
95 |
-
<td class="delim">
|
96 |
-
<input type="text" class="small" name="tags_delim" maxlength="1" value="<?php echo esc_attr($post['tags_delim']) ?>" />
|
97 |
-
<a href="#help" class="help" title="<?php _e('Delimiter used for tag list', 'pmxi_plugin') ?>">?</a>
|
98 |
-
</td>
|
99 |
-
</tr>
|
100 |
-
<tr>
|
101 |
-
<td colspan="3"> <a href="http://www.wpallimport.com/upgrade-to-pro?from=cpt" target="_blank">To import to Custom Post Types, upgrade to pro.</a> </td>
|
102 |
-
</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 |
-
|
135 |
-
|
136 |
-
|
137 |
-
</div>
|
138 |
-
</div>
|
139 |
-
<div class="post-type-container">
|
140 |
-
<h3>
|
141 |
-
<input type="radio" id="type_page" name="type" value="page" <?php echo 'page' == $post['type'] ? 'checked="checked"' : '' ?> />
|
142 |
-
<label for="type_page"><?php _e('Create Pages', 'pmxi_plugin') ?></label>
|
143 |
-
</h3>
|
144 |
-
<div class="post-type-options">
|
145 |
-
<table class="form-table">
|
146 |
-
<tr>
|
147 |
-
<th><?php _e('Page Template', 'pmxi_plugin') ?></th>
|
148 |
-
<td>
|
149 |
-
<select name="page_template" id="page_template">
|
150 |
-
<option value='default'><?php _e('Default', 'pmxi_plugin') ?></option>
|
151 |
-
<?php page_template_dropdown($template); ?>
|
152 |
-
</select>
|
153 |
-
</td>
|
154 |
-
</tr>
|
155 |
-
<tr>
|
156 |
-
<th><?php _e('Parent Page', 'pmxi_plugin') ?></th>
|
157 |
-
<td>
|
158 |
-
<?php wp_dropdown_pages(array('post_type' => 'page', 'selected' => $post['parent'], 'name' => 'parent', 'show_option_none' => __('(no parent)', 'pmxi_plugin'), 'sort_column'=> 'menu_order, post_title',)) ?>
|
159 |
-
</td>
|
160 |
-
</tr>
|
161 |
-
<tr>
|
162 |
-
<th><?php _e('Order', 'pmxi_plugin') ?></th>
|
163 |
-
<td><input type="text" class="small-text" name="order" value="<?php echo esc_attr($post['order']) ?>" /></td>
|
164 |
-
</tr>
|
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
|
192 |
-
<
|
193 |
-
<
|
194 |
</td>
|
195 |
</tr>
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
<input type="checkbox" id="is_delete_source" name="is_delete_source" value="1" <?php echo $post['is_delete_source'] ? 'checked="checked"': '' ?>/>
|
222 |
-
<label for="is_delete_source"><?php _e('Delete source XML file after importing', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('This setting takes effect only when script has access rights to perform the action, e.g. file is not deleted when pulled via HTTP or delete permission is not granted to the user that script is executed under.', 'pmxi_plugin') ?>">?</a></label>
|
223 |
-
</div>
|
224 |
-
<?php endif ?>
|
225 |
-
<?php if (class_exists('PMLC_Plugin')): // option is only valid when `WP Wizard Cloak` pluign is enabled ?>
|
226 |
-
<div class="input">
|
227 |
-
<input type="hidden" name="is_cloak" value="0" />
|
228 |
-
<input type="checkbox" id="is_cloak" name="is_cloak" value="1" <?php echo $post['is_cloak'] ? 'checked="checked"': '' ?>/>
|
229 |
-
<label for="is_cloak"><?php _e('Auto-Cloak Links', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php printf(__('Automatically process all links present in body of created post or page with <b>%s</b> plugin', 'pmxi_plugin'), PMLC_Plugin::getInstance()->getName()) ?>">?</a></label>
|
230 |
-
</div>
|
231 |
-
<?php endif ?>
|
232 |
-
<?php if (in_array($source_type, array('url', 'ftp', 'file'))): ?>
|
233 |
-
<div class="input">
|
234 |
-
<input type="hidden" name="is_scheduled" value="0" />
|
235 |
-
<input type="checkbox" id="is_scheduled" class="switcher" name="is_scheduled" value="1" disabled="disabled"/>
|
236 |
-
<label for="is_scheduled"><?php _e('Recurring import', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Consider this option if you want this import task to be run automatically on regular basis.', 'pmxi_plugin') ?>">?</a></label>
|
237 |
-
<a href="http://www.wpallimport.com/upgrade-to-pro?from=ri" target="_blank">Upgrade to pro for recurring/scheduled imports.</a>
|
238 |
-
</div>
|
239 |
<?php endif ?>
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
<input type="radio" id="status_draft" name="status" value="draft" <?php echo 'draft' == $post['status'] ? 'checked="checked"' : '' ?> />
|
246 |
-
<label for="status_draft"><?php _e('Draft', 'pmxi_plugin') ?></label>
|
247 |
-
</div>
|
248 |
-
|
249 |
-
<h3><?php _e('Post Dates', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Use any format supported by <b>strtotime</b>', 'pmxi_plugin') ?>">?</a></h3>
|
250 |
-
<div class="input">
|
251 |
-
<input type="radio" id="date_type_specific" class="switcher" name="date_type" value="specific" checked="checked"/>
|
252 |
-
<label for="date_type_specific">
|
253 |
-
<?php _e('As specified', 'pmxi_plugin') ?>
|
254 |
-
</label>
|
255 |
-
<span class="switcher-target-date_type_specific" style="vertical-align:middle">
|
256 |
-
<input type="text" class="datepicker" name="date" value="<?php echo esc_attr($post['date']) ?>" />
|
257 |
-
</span>
|
258 |
-
</div>
|
259 |
-
<div class="input">
|
260 |
-
<input type="radio" id="date_type_random" class="switcher" value="random" disabled="disabled" />
|
261 |
-
<label for="date_type_random">
|
262 |
-
<?php _e('Random dates', 'pmxi_plugin') ?>
|
263 |
-
</label>
|
264 |
-
<span class="" style="vertical-align:middle">
|
265 |
-
<?php _e('between', 'pmxi_plugin') ?>
|
266 |
-
<input type="text" class="datepicker" name="date_start" value="<?php echo esc_attr($post['date_start']) ?>" />
|
267 |
-
<?php _e('and', 'pmxi_plugin') ?>
|
268 |
-
<input type="text" class="datepicker" name="date_end" value="<?php echo esc_attr($post['date_end']) ?>" />
|
269 |
-
</span>
|
270 |
-
<a href="http://www.wpallimport.com/upgrade-to-pro?from=rd" target="_blank">To create posts with random dates, upgrade to pro.</a>
|
271 |
-
</div>
|
272 |
-
|
273 |
-
<h3><?php _e('Custom Fields', 'pmxi_plugin') ?></h3>
|
274 |
-
<table class="form-table custom-params">
|
275 |
-
<thead>
|
276 |
-
<tr>
|
277 |
-
<td><?php _e('Name', 'pmxi_plugin') ?></td>
|
278 |
-
<td><?php _e('Value', 'pmxi_plugin') ?></td>
|
279 |
-
<td></td>
|
280 |
-
</tr>
|
281 |
-
</thead>
|
282 |
-
<tbody>
|
283 |
-
<tr class="form-field">
|
284 |
-
<td><input type="text" name="custom_name[]" value="" disabled="disabled"/></td>
|
285 |
-
<td><textarea name="custom_value[]" disabled="disabled"></textarea></td>
|
286 |
-
<td class="action remove"></td>
|
287 |
-
</tr>
|
288 |
-
<tr>
|
289 |
-
<td colspan="3"> <a href="http://www.wpallimport.com/upgrade-to-pro?from=cf" target="_blank">To import data to Custom Fields (including fields in Custom Post Types), upgrade to pro.</a> </td>
|
290 |
-
</tr>
|
291 |
-
</tbody>
|
292 |
-
</table>
|
293 |
-
<br />
|
294 |
-
<div>
|
295 |
-
<input type="hidden" name="comment_status" value="closed" />
|
296 |
-
<input type="checkbox" id="comment_status" name="comment_status" value="open" <?php echo 'open' == $post['comment_status'] ? 'checked="checked"' : '' ?> />
|
297 |
-
<label for="comment_status"><?php _e('Allow Comments', 'pmxi_plugin') ?></label>
|
298 |
-
</div>
|
299 |
-
<div>
|
300 |
-
<input type="hidden" name="ping_status" value="closed" />
|
301 |
-
<input type="checkbox" id="ping_status" name="ping_status" value="open" <?php echo 'open' == $post['ping_status'] ? 'checked="checked"' : '' ?> />
|
302 |
-
<label for="ping_status"><?php _e('Allow Trackbacks and Pingbacks', 'pmxi_plugin') ?></label>
|
303 |
-
</div>
|
304 |
-
|
305 |
-
<h3><?php _e('Post Author', 'pmxi_plugin') ?></h3>
|
306 |
-
<div>
|
307 |
-
<?php wp_dropdown_users(array('name' => 'author', 'selected' => $post['author'])); ?>
|
308 |
-
</div>
|
309 |
-
|
310 |
-
<h3><?php _e('Featured Image', 'pmxi_plugin') ?></h3>
|
311 |
-
<div>
|
312 |
-
<input type="text" name="featured_image" disabled="disabled" style="width:300px;" value="<?php echo esc_attr($post['featured_image']) ?>" /> <span>Separate multiple image URLs with commas</span> <br/>
|
313 |
-
<a href="http://www.wpallimport.com/upgade-to-pro?from=fi" target="_blank">To import images to the post image gallery and set the Featured Image, upgrade to pro.</a>
|
314 |
-
</div>
|
315 |
-
|
316 |
-
<h2><?php _e('Reimport / Update Options', 'pmxi_plugin') ?></h2>
|
317 |
-
<hr />
|
318 |
-
|
319 |
-
<h3>
|
320 |
-
<?php _e('Post Unique Key', 'pmxi_plugin') ?>
|
321 |
-
<a href="#help" class="help" title="<?php _e('XPath expression which is used to detect correspondence between previously imported records and new ones. An expression used for the title is suitable in the most cases, but using recurring tag unique attribute, e.g. ID, if present, is good alternative as well.', 'pmxi_plugin') ?>">?</a>
|
322 |
-
</h3>
|
323 |
-
<div class="input">
|
324 |
-
<input type="text" class="smaller-text" name="unique_key" value="<?php echo esc_attr($post['unique_key']) ?>" <?php echo ! ($this->isWizard && $update_previous->isEmpty()) ? 'disabled="disabled"' : '' ?>/>
|
325 |
-
</div>
|
326 |
-
<br />
|
327 |
-
<div>
|
328 |
-
<input type="hidden" name="is_delete_missing" value="0" />
|
329 |
-
<input type="checkbox" id="is_delete_missing" name="is_delete_missing" value="1" <?php echo $post['is_delete_missing'] ? 'checked="checked"': '' ?> />
|
330 |
-
<label for="is_delete_missing"><?php _e('Delete missing records', 'pmxi_plugin') ?></label>
|
331 |
-
<a href="#help" class="help" title="<?php _e('Check this option if you want to delete posts from previous import operation which are not found among newly impoprted set.', 'pmxi_plugin') ?>">?</a>
|
332 |
-
</div>
|
333 |
-
<div>
|
334 |
-
<input type="hidden" name="is_keep_former_posts" value="0" />
|
335 |
-
<input type="checkbox" id="is_keep_former_posts" name="is_keep_former_posts" value="1" <?php echo $post['is_keep_former_posts'] ? 'checked="checked"': '' ?> class="switcher switcher-reversed" />
|
336 |
-
<label for="is_keep_former_posts"><?php _e('Do not update already existing records', 'pmxi_plugin') ?></label>
|
337 |
-
<a href="#help" class="help" title="<?php _e('Check this option if you do not want to update already esisting records. The option is useful if you plan to manually edit imported records and do not want them to be overwritten.<br /><br /><b>Important</b>: The option applies to the posts or pages associated with the import being updated. To handle potential conflicts with post or pages which are not associated with this import please use `Check for duplicates` option in `General Options` secion above.', 'pmxi_plugin') ?>">?</a>
|
338 |
-
</div>
|
339 |
-
<div class="switcher-target-is_keep_former_posts">
|
340 |
-
<div>
|
341 |
-
<input type="hidden" name="is_keep_status" value="0" />
|
342 |
-
<input type="checkbox" id="is_keep_status" name="is_keep_status" value="1" <?php echo $post['is_keep_status'] ? 'checked="checked"': '' ?> />
|
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"': '' ?> />
|
355 |
-
<label for="is_keep_categories"><?php _e('Keep categories, tags and taxonomies', 'pmxi_plugin') ?></label>
|
356 |
-
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their category, tag and custom taxonomies associations upon reimport.', 'pmxi_plugin') ?>">?</a>
|
357 |
-
</div>
|
358 |
-
</div>
|
359 |
-
<div>
|
360 |
-
<input type="hidden" name="is_keep_attachments" value="0" />
|
361 |
-
<input type="checkbox" id="is_keep_attachments" name="is_keep_attachments" value="1" <?php echo $post['is_keep_attachments'] ? 'checked="checked"': '' ?> />
|
362 |
-
<label for="is_keep_attachments"><?php _e('Keep attachments when records removed', 'pmxi_plugin') ?></label>
|
363 |
-
<a href="#help" class="help" title="<?php _e('Check this option if you want attachments like featured image to be kept in media library after parent post or page is removed or replaced during reimport operation.', 'pmxi_plugin') ?>">?</a>
|
364 |
-
</div>
|
365 |
-
|
366 |
-
<br />
|
367 |
-
<p>
|
368 |
-
<?php wp_nonce_field('options', '_wpnonce_options') ?>
|
369 |
-
<input type="hidden" name="is_submitted" value="1" />
|
370 |
-
|
371 |
-
<?php if ($this->isWizard): ?>
|
372 |
-
<a href="<?php echo add_query_arg('action', 'template', $this->baseUrl) ?>" class="button back"><?php _e('Back', 'pmxi_plugin') ?></a>
|
373 |
-
|
374 |
-
<input type="submit" class="button-primary ajax-import" value="<?php _e('Save & Create Posts', 'pmxi_plugin') ?>" />
|
375 |
-
|
376 |
-
<?php if (in_array($source_type, array('url', 'ftp', 'file'))): ?>
|
377 |
-
or
|
378 |
-
<input type="submit" name="save_only" class="button" value="<?php _e('Save Only', 'pmxi_plugin') ?>" />
|
379 |
-
<?php endif ?>
|
380 |
-
|
381 |
-
<?php else: ?>
|
382 |
-
<input type="submit" class="button-primary" value="<?php _e('Edit', 'pmxi_plugin') ?>" />
|
383 |
-
<?php endif ?>
|
384 |
-
</p>
|
385 |
-
|
386 |
</td>
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
<?php $this->tag() ?>
|
391 |
-
</td>
|
392 |
-
<?php endif ?>
|
393 |
-
</tr>
|
394 |
-
</table>
|
395 |
-
</form>
|
396 |
-
<script type="text/javascript">
|
397 |
-
(function($){$(function(){
|
398 |
-
$('select[name="custom_type"]').change(function () {
|
399 |
-
var type = $(this).val(); if ('' == type) type = 'post';
|
400 |
-
$('tr.post_taxonomy').each(function () {
|
401 |
-
$(this)[$.inArray(type, $(this).data('type').split(' ')) < 0 ? 'hide' : 'fadeIn']();
|
402 |
-
});
|
403 |
-
}).change();
|
404 |
-
});})(jQuery);
|
405 |
-
</script>
|
1 |
<?php
|
2 |
+
|
3 |
if (!function_exists('reverse_taxonomies_html')) {
|
4 |
+
function reverse_taxonomies_html($post_taxonomies, $item_id, &$i){
|
5 |
$childs = array();
|
6 |
+
foreach ($post_taxonomies as $j => $cat) if ($cat->parent_id == $item_id) { $childs[] = $cat; }
|
7 |
+
|
8 |
if (!empty($childs)){
|
9 |
?>
|
10 |
<ol>
|
11 |
<?php
|
12 |
foreach ($childs as $child_cat){
|
13 |
$i++;
|
14 |
+
?>
|
15 |
<li id="item_<?php echo $i; ?>">
|
16 |
+
<div class="drag-element"><input type="checkbox" class="assign_post" <?php if ($child_cat->assign): ?>checked="checked"<?php endif; ?>/><input class="widefat" type="text" value="<?php echo $child_cat->xpath; ?>"/></div><a href="javascript:void(0);" class="icon-item remove-ico"></a>
|
17 |
<?php echo reverse_taxonomies_html($post_taxonomies, $child_cat->item_id, $i); ?>
|
18 |
+
</li>
|
19 |
<?php
|
20 |
}
|
21 |
?>
|
25 |
}
|
26 |
}
|
27 |
?>
|
28 |
+
<?php $custom_types = get_post_types(array('_builtin' => false), 'objects'); ?>
|
29 |
+
<input type="hidden" id="selected_post_type" value="<?php echo (!empty($post['custom_type'])) ? $post['custom_type'] : '';?>">
|
30 |
+
<input type="hidden" id="selected_type" value="<?php echo (!empty($post['type'])) ? $post['type'] : '';?>">
|
31 |
+
<h2>
|
32 |
+
<?php if ($this->isWizard): ?>
|
33 |
+
<?php _e('Import XML/CSV - Step 4: Options', 'pmxi_plugin') ?>
|
34 |
+
<?php else: ?>
|
35 |
+
<?php _e('Edit Import Options', 'pmxi_plugin') ?>
|
36 |
+
<?php endif ?>
|
37 |
+
</h2>
|
38 |
+
<h3>Click the appropriate tab to choose the type of posts to create.</h3>
|
39 |
+
|
40 |
+
<?php if ($this->errors->get_error_codes()): ?>
|
41 |
+
<?php $this->error() ?>
|
42 |
+
<?php endif ?>
|
43 |
+
<table class="layout">
|
44 |
+
<tr>
|
45 |
+
<td class="left">
|
46 |
+
<?php if ($this->isWizard): ?>
|
47 |
+
<?php if ($is_loaded_template && !$load_options): ?>
|
48 |
+
<form class="options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
|
49 |
+
<span class="load-options">
|
50 |
+
Load Options... <input type="checkbox" name="load_options" /><a class="help" href="#help" original-title="Load options from selected template.">?</a>
|
51 |
</span>
|
52 |
+
</form>
|
53 |
+
<?php elseif ($is_loaded_template): ?>
|
54 |
+
<form class="options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
|
55 |
+
<span class="load-options">
|
56 |
+
Reset Options... <input type="checkbox" name="reset_options" /><a class="help" href="#help" original-title="Reset options.">?</a>
|
57 |
</span>
|
58 |
+
</form>
|
59 |
+
<?php endif; ?>
|
60 |
+
<?php endif; ?>
|
61 |
+
<div id="pmxi_tabs">
|
62 |
+
<ul>
|
63 |
+
<li><a href="#tabs-1">Posts</a></li>
|
64 |
+
<li><a href="#tabs-2">Pages</a></li>
|
65 |
+
<?php if (count($custom_types)): ?>
|
66 |
+
<?php foreach ($custom_types as $key => $ct): ?>
|
67 |
+
<li><a href="#tabs-<?php echo $key; ?>"><?php echo $ct->labels->name ?></a></li>
|
68 |
+
<?php endforeach ?>
|
69 |
<?php endif ?>
|
70 |
+
</ul>
|
71 |
+
|
72 |
+
<!-- Post Options -->
|
73 |
+
|
74 |
+
<div id="tabs-1"> <!-- Basic -->
|
75 |
+
<form class="options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
|
76 |
+
<input type="hidden" name="type" value="post"/>
|
77 |
+
<input type="hidden" name="custom_type" value=""/>
|
78 |
+
<div class="post-type-options">
|
79 |
+
<table class="form-table" style="max-width:none;">
|
80 |
+
<?php
|
81 |
+
$post_type = 'post';
|
82 |
+
$entry = 'post';
|
83 |
+
include( 'options/_main_options_template.php' );
|
84 |
+
include( 'options/_taxonomies_template.php' );
|
85 |
+
include( 'options/_categories_template.php' );
|
86 |
+
include( 'options/_custom_fields_template.php' );
|
87 |
+
include( 'options/_featured_template.php' );
|
88 |
+
include( 'options/_author_template.php' );
|
89 |
+
include( 'options/_reimport_template.php' );
|
90 |
+
?>
|
91 |
+
</table>
|
92 |
+
</div>
|
93 |
+
|
94 |
+
<?php include( 'options/_buttons_template.php' ); ?>
|
95 |
+
|
96 |
+
</form>
|
97 |
+
</div>
|
98 |
+
|
99 |
+
<!-- Page Options -->
|
100 |
+
|
101 |
+
<div id="tabs-2">
|
102 |
+
<form class="options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
|
103 |
+
<input type="hidden" name="type" value="page"/>
|
104 |
+
<input type="hidden" name="custom_type" value=""/>
|
105 |
+
<div class="post-type-options">
|
106 |
+
<table class="form-table" style="max-width:none;">
|
107 |
+
|
108 |
+
<?php include( 'options/_main_options_template.php' ); ?>
|
109 |
+
|
110 |
<tr>
|
111 |
+
<td align="center" width="33%">
|
112 |
+
<label><?php _e('Page Template', 'pmxi_plugin') ?></label> <br>
|
113 |
+
<select name="page_template" id="page_template">
|
114 |
+
<option value='default'><?php _e('Default', 'pmxi_plugin') ?></option>
|
115 |
+
<?php page_template_dropdown($post['page_template']); ?>
|
116 |
+
</select>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
</td>
|
118 |
+
<td align="center" width="33%">
|
119 |
+
<label><?php _e('Parent Page', 'pmxi_plugin') ?></label> <br>
|
120 |
+
<?php wp_dropdown_pages(array('post_type' => 'page', 'selected' => $post['parent'], 'name' => 'parent', 'show_option_none' => __('(no parent)', 'pmxi_plugin'), 'sort_column'=> 'menu_order, post_title',)) ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
</td>
|
122 |
+
<td align="center" width="33%">
|
123 |
+
<label><?php _e('Order', 'pmxi_plugin') ?></label> <br>
|
124 |
+
<input type="text" class="" name="order" value="<?php echo esc_attr($post['order']) ?>" />
|
125 |
</td>
|
126 |
</tr>
|
127 |
+
<?php
|
128 |
+
$post_type = 'post';
|
129 |
+
$entry = 'page';
|
130 |
+
include( 'options/_taxonomies_template.php' );
|
131 |
+
include( 'options/_featured_template.php' );
|
132 |
+
include( 'options/_reimport_template.php' );
|
133 |
+
?>
|
134 |
+
</table>
|
135 |
+
</div>
|
136 |
+
|
137 |
+
<?php include( 'options/_buttons_template.php' ); ?>
|
138 |
+
|
139 |
+
</form>
|
140 |
+
</div>
|
141 |
+
|
142 |
+
<!-- Custom Post Types -->
|
143 |
+
|
144 |
+
<?php if (count($custom_types)): ?>
|
145 |
+
<?php foreach ($custom_types as $key => $ct): ?>
|
146 |
+
<div id="tabs-<?php echo $key;?>">
|
147 |
+
|
148 |
+
<p><a href="http://www.wpallimport.com/upgrade-to-pro?from=upi" target="_blank" class="upgrade_link">Upgrade to the paid edition of WP All Import to use this feature.</a></p>
|
149 |
+
|
150 |
+
</div>
|
151 |
+
<?php endforeach ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
<?php endif ?>
|
153 |
+
</div>
|
154 |
+
</td>
|
155 |
+
<?php if ($this->isWizard or $this->isTemplateEdit): ?>
|
156 |
+
<td class="right options">
|
157 |
+
<?php $this->tag() ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
</td>
|
159 |
+
<?php endif ?>
|
160 |
+
</tr>
|
161 |
+
</table>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
views/admin/import/options/_author_template.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<tr>
|
2 |
+
<td colspan="3">
|
3 |
+
<h3><?php _e('Post Author', 'pmxi_plugin') ?></h3>
|
4 |
+
<div>
|
5 |
+
<input type="text" name="author" value="<?php echo esc_attr($post['author']) ?>"/> <a href="#help" class="help" title="<?php _e('Value that contains user ID, login, slug or email.', 'pmxi_plugin') ?>">?</a>
|
6 |
+
</div>
|
7 |
+
</td>
|
8 |
+
</tr>
|
9 |
+
<tr>
|
10 |
+
<td colspan="3">
|
11 |
+
<h3><?php _e('Post Excerpt', 'pmxi_plugin') ?></h3>
|
12 |
+
<div>
|
13 |
+
<input type="text" name="post_excerpt" style="width:100%;" value="<?php echo esc_attr($post['post_excerpt']) ?>" />
|
14 |
+
</div>
|
15 |
+
<h3><?php _e('Post Slug', 'pmxi_plugin') ?></h3>
|
16 |
+
<div>
|
17 |
+
<input type="text" name="post_slug" style="width:100%;" value="<?php echo esc_attr($post['post_slug']) ?>" />
|
18 |
+
</div> <br><br>
|
19 |
+
</td>
|
20 |
+
</tr>
|
views/admin/import/options/_buttons_template.php
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<br>
|
2 |
+
<div class="input">
|
3 |
+
<label for="save_import_as">Friendly Name</label> <input type="text" name="friendly_name" title="<?php _e('Save friendly name...', 'pmxi_plugin') ?>" style="vertical-align:middle; font-size:11px; background:#fff !important;" value="<?php echo esc_attr($post['friendly_name']) ?>" />
|
4 |
+
</div>
|
5 |
+
<br>
|
6 |
+
<?php if ($_SESSION['pmxi_import']['large_file'] or (!empty($import) and $import->large_import == 'Yes')):?>
|
7 |
+
<div class="input">
|
8 |
+
<label for="records_per_request">Records Per Iteration</label> <input type="text" name="records_per_request" style="vertical-align:middle; font-size:11px; background:#fff !important; width: 40px;" value="<?php echo esc_attr($post['records_per_request']) ?>" />
|
9 |
+
<a href="#help" class="help" title="<?php _e('Your feed was detected as a "large" file. The import process will be executed via AJAX requests. To make import process faster you can increase the number of records imported per iteration. Higher numbers put more strain on your server but make the import process take less time. 10 is a very safe number. To speed up the process, try 100 or more, especially if your import settings are simple and you are not downloading images.', 'pmxi_plugin') ?>">?</a>
|
10 |
+
</div>
|
11 |
+
<div class="input">
|
12 |
+
<input type="hidden" name="create_chunks" value="0" />
|
13 |
+
<input type="checkbox" id="create_chunks_<?php echo $entry; ?>" name="create_chunks" value="1" <?php echo $post['create_chunks'] ? 'checked="checked"': '' ?>/>
|
14 |
+
<label for="create_chunks_<?php echo $entry; ?>"><?php _e('create chunks', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('This setting will split importing feed to chunks with 100 records per chunk.', 'pmxi_plugin') ?>">?</a></label>
|
15 |
+
</div>
|
16 |
+
<br>
|
17 |
+
<?php endif; ?>
|
18 |
+
<div class="input">
|
19 |
+
<input type="hidden" name="is_import_specified" value="0" />
|
20 |
+
<input type="checkbox" id="is_import_specified_<?php echo $entry; ?>" class="switcher" name="is_import_specified" value="1" <?php echo $post['is_import_specified'] ? 'checked="checked"': '' ?>/>
|
21 |
+
<label for="is_import_specified_<?php echo $entry; ?>"><?php _e('Import only specified records', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Enter records or record ranges separated by commas, e.g. <b>1,5,7-10</b> would import the first, the fifth, and the seventh to tenth.', 'pmxi_plugin') ?>">?</a></label>
|
22 |
+
<span class="switcher-target-is_import_specified_<?php echo $entry; ?>" style="vertical-align:middle">
|
23 |
+
<div class="input" style="display:inline;">
|
24 |
+
<input type="text" name="import_specified" value="<?php echo esc_attr($post['import_specified']) ?>" style="width:50%;"/>
|
25 |
+
</div>
|
26 |
+
</span>
|
27 |
+
</div>
|
28 |
+
<?php if (in_array($source_type, array('ftp', 'file'))): ?>
|
29 |
+
<div class="input">
|
30 |
+
<input type="hidden" name="is_delete_source" value="0" />
|
31 |
+
<input type="checkbox" id="is_delete_source_<?php echo $entry; ?>" name="is_delete_source" value="1" <?php echo $post['is_delete_source'] ? 'checked="checked"': '' ?>/>
|
32 |
+
<label for="is_delete_source_<?php echo $entry; ?>"><?php _e('Delete source XML file after importing', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('This setting takes effect only when script has access rights to perform the action, e.g. file is not deleted when pulled via HTTP or delete permission is not granted to the user that script is executed under.', 'pmxi_plugin') ?>">?</a></label>
|
33 |
+
</div>
|
34 |
+
<?php endif; ?>
|
35 |
+
<?php if (class_exists('PMLC_Plugin')): // option is only valid when `WP Wizard Cloak` pluign is enabled ?>
|
36 |
+
<div class="input">
|
37 |
+
<input type="hidden" name="is_cloak" value="0" />
|
38 |
+
<input type="checkbox" id="is_cloak_<?php echo $entry; ?>" name="is_cloak" value="1" <?php echo $post['is_cloak'] ? 'checked="checked"': '' ?>/>
|
39 |
+
<label for="is_cloak_<?php echo $entry; ?>"><?php _e('Auto-Cloak Links', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php printf(__('Automatically process all links present in body of created post or page with <b>%s</b> plugin', 'pmxi_plugin'), PMLC_Plugin::getInstance()->getName()) ?>">?</a></label>
|
40 |
+
</div> <br>
|
41 |
+
<?php endif; ?>
|
42 |
+
<p class="submit-buttons">
|
43 |
+
<?php wp_nonce_field('options', '_wpnonce_options') ?>
|
44 |
+
<input type="hidden" name="is_submitted" value="1" />
|
45 |
+
|
46 |
+
<?php if ($this->isWizard): ?>
|
47 |
+
|
48 |
+
<a href="<?php echo add_query_arg('action', 'template', $this->baseUrl) ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
|
49 |
+
|
50 |
+
<?php if (in_array($source_type, array('url', 'ftp', 'file'))): ?>
|
51 |
+
<input type="hidden" class="save_only" value="0" name="save_only"/>
|
52 |
+
<span style="font-size:16px;">or</span> <input type="submit" name="btn_save_only" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Save Only', 'pmxi_plugin') ?>" />
|
53 |
+
<?php endif ?>
|
54 |
+
|
55 |
+
<input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Finish', 'pmxi_plugin') ?>" />
|
56 |
+
|
57 |
+
<?php else: ?>
|
58 |
+
<a href="<?php echo remove_query_arg('id', remove_query_arg('action', $this->baseUrl)); ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
|
59 |
+
<input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Save', 'pmxi_plugin') ?>" />
|
60 |
+
<?php endif ?>
|
61 |
+
</p>
|
views/admin/import/options/_categories_template.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<tr>
|
2 |
+
<td colspan="3">
|
3 |
+
<div class="col2">
|
4 |
+
<fieldset style="margin-left:0px;">
|
5 |
+
<legend><?php _e('Categories', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Uncheck a box and the category will still be created, but the post will not be assigned to it.', 'pmxi_plugin') ?>">?</a></legend>
|
6 |
+
<ol class="sortable no-margin">
|
7 |
+
<?php if (!empty($post['categories'])):?>
|
8 |
+
<?php
|
9 |
+
$categories = json_decode($post['categories']);
|
10 |
+
|
11 |
+
if (empty($categories)) $categories = explode(',', $post['categories']);
|
12 |
+
|
13 |
+
if (!empty($categories) and is_array($categories)): $i = 0; foreach ($categories as $cat) { $i++;
|
14 |
+
if (is_null($cat->parent_id) or empty($cat->parent_id))
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<li id="item_<?php echo $i; ?>">
|
18 |
+
<div class="drag-element"><input type="checkbox" class="assign_post" <?php if ($cat->assign): ?>checked="checked"<?php endif; ?>/><input type="text" class="widefat" value="<?php echo (is_object($cat)) ? $cat->xpath : $cat; ?>"/></div><?php if ($i>1):?><a href="javascript:void(0);" class="icon-item remove-ico"></a><?php endif;?>
|
19 |
+
<?php if (is_object($cat)) echo reverse_taxonomies_html($categories, $cat->item_id, $i); ?>
|
20 |
+
</li>
|
21 |
+
<?php
|
22 |
+
}
|
23 |
+
}; else: ?>
|
24 |
+
<li id="item_1"><div class="drag-element"><input type="checkbox" class="assign_post" checked="checked"/><input type="text" class="widefat" value=""/></div></li>
|
25 |
+
<?php endif;?>
|
26 |
+
<?php else: ?>
|
27 |
+
<li id="item_1"><div class="drag-element"><input type="checkbox" class="assign_post" checked="checked"/><input type="text" class="widefat" value=""/></div></li>
|
28 |
+
<?php endif; ?>
|
29 |
+
</ol>
|
30 |
+
<a href="javascript:void(0);" class="icon-item add-new-ico">Add more</a> <br><br>
|
31 |
+
<input type="hidden" class="hierarhy-output" name="categories" value="<?php echo esc_attr($post['categories']) ?>"/>
|
32 |
+
<div class="hidden" id="dialog-confirm-category-removing" title="Delete categories?">Remove only current category or current category with subcategories?</div>
|
33 |
+
<div class="delim">
|
34 |
+
<label><?php _e('Separated by', 'pmxi_plugin'); ?></label>
|
35 |
+
<input type="text" class="small" name="categories_delim" maxlength="1" value="<?php echo esc_attr($post['categories_delim']) ?>" />
|
36 |
+
<!--a href="#help" class="help" title="<?php _e('Delimiter used for tag list', 'pmxi_plugin') ?>">?</a-->
|
37 |
+
</div>
|
38 |
+
</fieldset>
|
39 |
+
</div>
|
40 |
+
<div class="col2">
|
41 |
+
<fieldset style="padding:5px; margin-right:0px;">
|
42 |
+
<legend><?php _e('Tags', 'pmxi_plugin') ?> </legend>
|
43 |
+
<!--a href="#help" class="help" title="<?php _e('Enter tags separated by commas.', 'pmxi_plugin') ?>">?</a-->
|
44 |
+
<input type="text" name="tags" class="widefat" value="<?php echo esc_attr($post['tags']) ?>" /> <br> <br>
|
45 |
+
<div class="delim">
|
46 |
+
<label><?php _e('Separated by', 'pmxi_plugin'); ?></label>
|
47 |
+
<input type="text" class="small" name="tags_delim" maxlength="1" value="<?php echo esc_attr($post['tags_delim']) ?>" />
|
48 |
+
<!--a href="#help" class="help" title="<?php _e('Delimiter used for tag list', 'pmxi_plugin') ?>">?</a-->
|
49 |
+
</div>
|
50 |
+
</fieldset>
|
51 |
+
</div>
|
52 |
+
</td>
|
53 |
+
</tr>
|
views/admin/import/options/_custom_fields_template.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<tr>
|
2 |
+
<td colspan="3" style="border-bottom:1px solid #ccc;">
|
3 |
+
<fieldset class="optionsset" style="text-align:center;">
|
4 |
+
<legend>Custom Fields</legend>
|
5 |
+
<table class="form-table custom-params" style="max-width:none; border:none;">
|
6 |
+
<thead>
|
7 |
+
<tr>
|
8 |
+
<td><?php _e('Name', 'pmxi_plugin') ?></td>
|
9 |
+
<td><?php _e('Value', 'pmxi_plugin') ?></td>
|
10 |
+
<td></td>
|
11 |
+
</tr>
|
12 |
+
</thead>
|
13 |
+
<tbody>
|
14 |
+
<tr class="form-field">
|
15 |
+
<td><input type="text" name="custom_name[]" value="" disabled="disabled" /></td>
|
16 |
+
<td class="action remove">
|
17 |
+
<textarea name="custom_value[]" disabled="disabled"></textarea>
|
18 |
+
</td>
|
19 |
+
</tr>
|
20 |
+
<tr>
|
21 |
+
<td colspan="3"><a href="#add" title="<?php _e('add', 'pmxi_plugin')?>" class="action add-new-custom"><?php _e('Add more', 'pmxi_plugin') ?></a></td>
|
22 |
+
</tr>
|
23 |
+
</tbody>
|
24 |
+
</table>
|
25 |
+
<select class="existing_meta_keys">
|
26 |
+
<option value="">Existing Custom Fields...</option>
|
27 |
+
<?php
|
28 |
+
$hide_fields = array('_wp_page_template', '_edit_lock', '_edit_last', '_wp_trash_meta_status', '_wp_trash_meta_time');
|
29 |
+
if (!empty($meta_keys) and $meta_keys->count()):
|
30 |
+
foreach ($meta_keys as $meta_key) { if (in_array($meta_key['meta_key'], $hide_fields) or strpos($meta_key['meta_key'], '_wp') === 0) continue;
|
31 |
+
?>
|
32 |
+
<option value="<?php echo $meta_key['meta_key'];?>"><?php echo $meta_key['meta_key'];?></option>
|
33 |
+
<?php
|
34 |
+
}
|
35 |
+
endif;
|
36 |
+
?>
|
37 |
+
</select>
|
38 |
+
<br><br>
|
39 |
+
<a href="http://www.wpallimport.com/upgrade-to-pro?from=upi" target="_blank" class="upgrade_link">Upgrade to the paid edition of WP All Import to use this feature.</a>
|
40 |
+
</fieldset>
|
41 |
+
<br>
|
42 |
+
</td>
|
43 |
+
</tr>
|
views/admin/import/options/_featured_template.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<tr>
|
2 |
+
<td colspan="3">
|
3 |
+
<h3>
|
4 |
+
<?php _e('Download & Import Images To The Post Media Gallery', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Specify URLs or XPath Template Tags to download and import images to the post media gallery. The first image will be set as the Featured Image. Example: <pre>{image[1]},{image[2]},{image[3]}</pre> Separate your URLs or XPath Template Tags with the comma. <i>Separated by</i> character will use if xPath value contains multiple URLs, for example: <br> \'http://test.com/first.jpg | http://test.com/second.png\'.', 'pmxi_plugin') ?>">?</a>
|
5 |
+
<span class="separated_by">Separated by</span>
|
6 |
+
</h3>
|
7 |
+
<div>
|
8 |
+
<input type="text" name="featured_image" style="width:92%;" value="<?php echo esc_attr($post['featured_image']) ?>" disabled="disabled"/>
|
9 |
+
<input type="text" class="small" name="featured_delim" maxlength="1" value="<?php echo esc_attr($post['featured_delim']) ?>" style="width:5%; text-align:center;" disabled="disabled"/>
|
10 |
+
</div>
|
11 |
+
<div class="input">
|
12 |
+
<input type="hidden" name="create_draft" value="no" />
|
13 |
+
<input type="checkbox" id="create_draft_<?php echo $entry; ?>" name="create_draft" value="yes" <?php echo 'yes' == $post['create_draft'] ? 'checked="checked"' : '' ?> disabled="disabled"/>
|
14 |
+
<label for="create_draft_<?php echo $entry; ?>"><?php _e('<small>If no images are downloaded successfully, create entry as Draft.</small>', 'pmxi_plugin') ?></label>
|
15 |
+
</div>
|
16 |
+
<a href="http://www.wpallimport.com/upgrade-to-pro?from=upi" target="_blank" class="upgrade_link">Upgrade to the paid edition of WP All Import to use this feature.</a>
|
17 |
+
<h3>
|
18 |
+
<?php _e('Download & Import Attachments', 'pmxi_plugin') ?>
|
19 |
+
<span class="separated_by">Separated by</span>
|
20 |
+
</h3>
|
21 |
+
<div>
|
22 |
+
<input type="text" name="attachments" style="width:92%;" value="<?php echo esc_attr($post['attachments']) ?>" />
|
23 |
+
<input type="text" class="small" name="atch_delim" maxlength="1" value="<?php echo esc_attr($post['atch_delim']) ?>" style="width:5%; text-align:center;"/>
|
24 |
+
</div>
|
25 |
+
<br>
|
26 |
+
</td>
|
27 |
+
</tr>
|
views/admin/import/options/_main_options_template.php
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<tr>
|
2 |
+
<td colspan="3" style="border-bottom:1px solid #ccc;">
|
3 |
+
<div class="col2" style="margin-bottom:20px;">
|
4 |
+
<h3><?php _e('Post Status', 'pmxi_plugin') ?></h3>
|
5 |
+
<div>
|
6 |
+
<div class="input">
|
7 |
+
<input type="radio" id="status_publish_<?php echo $entry; ?>" name="status" value="publish" <?php echo 'publish' == $post['status'] ? 'checked="checked"' : '' ?> />
|
8 |
+
<label for="status_publish_<?php echo $entry; ?>"><?php _e('Published', 'pmxi_plugin') ?></label>
|
9 |
+
</div>
|
10 |
+
<div class="input">
|
11 |
+
<input type="radio" id="status_draft_<?php echo $entry; ?>" name="status" value="draft" <?php echo 'draft' == $post['status'] ? 'checked="checked"' : '' ?> />
|
12 |
+
<label for="status_draft_<?php echo $entry; ?>"><?php _e('Draft', 'pmxi_plugin') ?></label>
|
13 |
+
</div>
|
14 |
+
<br>
|
15 |
+
<div class="input">
|
16 |
+
<input type="hidden" name="comment_status" value="closed" />
|
17 |
+
<input type="checkbox" id="comment_status_<?php echo $entry; ?>" name="comment_status" value="open" <?php echo 'open' == $post['comment_status'] ? 'checked="checked"' : '' ?> />
|
18 |
+
<label for="comment_status_<?php echo $entry; ?>"><?php _e('Allow Comments', 'pmxi_plugin') ?></label>
|
19 |
+
</div>
|
20 |
+
<div class="input">
|
21 |
+
<input type="hidden" name="ping_status" value="closed" />
|
22 |
+
<input type="checkbox" id="ping_status_<?php echo $entry; ?>" name="ping_status" value="open" <?php echo 'open' == $post['ping_status'] ? 'checked="checked"' : '' ?> />
|
23 |
+
<label for="ping_status_<?php echo $entry; ?>"><?php _e('Allow Trackbacks and Pingbacks', 'pmxi_plugin') ?></label>
|
24 |
+
</div>
|
25 |
+
</div>
|
26 |
+
</div>
|
27 |
+
<div class="col2">
|
28 |
+
<h3><?php _e('Post Dates', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Use any format supported by the PHP <b>strtotime</b> function. That means pretty much any human-readable date will work.', 'pmxi_plugin') ?>">?</a></h3>
|
29 |
+
<div class="input">
|
30 |
+
<input type="radio" id="date_type_specific_<?php echo $entry; ?>" class="switcher" name="date_type" value="specific" <?php echo 'random' != $post['date_type'] ? 'checked="checked"' : '' ?> />
|
31 |
+
<label for="date_type_specific_<?php echo $entry; ?>">
|
32 |
+
<?php _e('As specified', 'pmxi_plugin') ?>
|
33 |
+
</label>
|
34 |
+
<span class="switcher-target-date_type_specific_<?php echo $entry; ?>" style="vertical-align:middle">
|
35 |
+
<input type="text" class="datepicker" name="date" value="<?php echo esc_attr($post['date']) ?>" style="width:40%;"/>
|
36 |
+
</span>
|
37 |
+
</div>
|
38 |
+
<div class="input">
|
39 |
+
<input type="radio" id="date_type_random_<?php echo $entry; ?>" class="switcher" name="date_type" value="random" <?php echo 'random' == $post['date_type'] ? 'checked="checked"' : '' ?> />
|
40 |
+
<label for="date_type_random_<?php echo $entry; ?>">
|
41 |
+
<?php _e('Random dates', 'pmxi_plugin') ?><a href="#help" class="help" title="<?php _e('Posts will be randomly assigned dates in this range. WordPress ensures posts with dates in the future will not appear until their date has been reached.', 'pmxi_plugin') ?>">?</a>
|
42 |
+
</label> <br>
|
43 |
+
<span class="switcher-target-date_type_random_<?php echo $entry; ?>" style="vertical-align:middle">
|
44 |
+
<input type="text" class="datepicker" name="date_start" value="<?php echo esc_attr($post['date_start']) ?>" />
|
45 |
+
<?php _e('and', 'pmxi_plugin') ?>
|
46 |
+
<input type="text" class="datepicker" name="date_end" value="<?php echo esc_attr($post['date_end']) ?>" />
|
47 |
+
</span>
|
48 |
+
</div>
|
49 |
+
</div>
|
50 |
+
<!--div class="col3 last">
|
51 |
+
<div class="input">
|
52 |
+
<input type="hidden" name="is_duplicates" value="0" />
|
53 |
+
<input type="checkbox" id="is_duplicates_<?php echo $entry; ?>" class="switcher" name="is_duplicates" value="1" <?php echo $post['is_duplicates'] ? 'checked="checked"': '' ?>/>
|
54 |
+
<label for="is_duplicates_<?php echo $entry; ?>"><?php _e('Check for duplicates', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('This option allows you to specify action for articles being imported which have duplicates in WordPress database.<br /><br /><b>Important</b>: This option applies only to pages or posts not associated with current import. To manage overwrite rules for records previously created by import operation currently being updated please see `Reimport / Update Options` section below.', 'pmxi_plugin') ?>">?</a></label>
|
55 |
+
<div class="switcher-target-is_duplicates_<?php echo $entry; ?>">
|
56 |
+
<div class="input">
|
57 |
+
<span style="vertical-align:middle"><?php _e('Determine duplicates by', 'pmxi_plugin') ?></span><br>
|
58 |
+
<input type="radio" id="duplicate_indicator_title_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="title" <?php echo 'title' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?>/>
|
59 |
+
<label for="duplicate_indicator_title_<?php echo $entry; ?>"><?php _e('title', 'pmxi_plugin' )?></label><br>
|
60 |
+
<input type="radio" id="duplicate_indicator_content_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="content" <?php echo 'content' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?>/>
|
61 |
+
<label for="duplicate_indicator_content_<?php echo $entry; ?>"><?php _e('content', 'pmxi_plugin' )?></label><br>
|
62 |
+
<input type="radio" id="duplicate_indicator_custom_field_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="custom field" <?php echo 'custom field' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?>/>
|
63 |
+
<label for="duplicate_indicator_custom_field_<?php echo $entry; ?>"><?php _e('custom field', 'pmxi_plugin' )?></label><br>
|
64 |
+
<span class="switcher-target-duplicate_indicator_custom_field_<?php echo $entry; ?>" style="vertical-align:middle">
|
65 |
+
<?php _e('Name', 'pmxi_plugin') ?>
|
66 |
+
<input type="text" name="custom_duplicate_name" value="<?php echo esc_attr($post['custom_duplicate_name']) ?>" /><br>
|
67 |
+
<?php _e('Value', 'pmxi_plugin') ?>
|
68 |
+
<input type="text" name="custom_duplicate_value" value="<?php echo esc_attr($post['custom_duplicate_value']) ?>" />
|
69 |
+
</span>
|
70 |
+
</div>
|
71 |
+
<div class="input">
|
72 |
+
<span style="vertical-align:middle"><?php _e('When found:', 'pmxi_plugin') ?></span> <br>
|
73 |
+
<input type="radio" id="duplicate_action_keep_<?php echo $entry; ?>" name="duplicate_action" value="keep" <?php echo 'keep' == $post['duplicate_action'] ? 'checked="checked"': '' ?> class="switcher"/>
|
74 |
+
<label for="duplicate_action_keep_<?php echo $entry; ?>"><?php _e('keep existing and skip new', 'pmxi_plugin' )?></label> <br>
|
75 |
+
<input type="radio" id="duplicate_action_rewrite_<?php echo $entry; ?>" name="duplicate_action" value="rewrite" <?php echo 'rewrite' == $post['duplicate_action'] ? 'checked="checked"': '' ?> class="switcher"/>
|
76 |
+
<label for="duplicate_action_rewrite_<?php echo $entry; ?>"><?php _e('remove existing and add new', 'pmxi_plugin' )?></label> <br>
|
77 |
+
<input type="radio" id="duplicate_action_update_<?php echo $entry; ?>" name="duplicate_action" value="update" <?php echo 'update' == $post['duplicate_action'] ? 'checked="checked"': '' ?> class="switcher"/>
|
78 |
+
<label for="duplicate_action_update_<?php echo $entry; ?>"><?php _e('update existing', 'pmxi_plugin' )?></label>
|
79 |
+
<span class="switcher-target-duplicate_action_update_<?php echo $entry; ?>" style="vertical-align:middle">
|
80 |
+
<div class="input" style="padding-left:20px;">
|
81 |
+
<input type="hidden" name="not_create_records" value="0" />
|
82 |
+
<input type="checkbox" id="not_create_records_<?php echo $entry; ?>" name="not_create_records" value="1" <?php echo $post['not_create_records'] ? 'checked="checked"' : '' ?> />
|
83 |
+
<label for="not_create_records_<?php echo $entry; ?>"><?php _e('NOT create new records', 'pmxi_plugin') ?></label>
|
84 |
+
</div>
|
85 |
+
</span>
|
86 |
+
</div>
|
87 |
+
</div>
|
88 |
+
</div>
|
89 |
+
</div-->
|
90 |
+
</td>
|
91 |
+
</tr>
|
92 |
+
<tr>
|
93 |
+
<td colspan="3">
|
94 |
+
<h3 style="text-align:center; color:#999;">Drag elements from the XML tree on the right to any textbox below.</h3>
|
95 |
+
</td>
|
96 |
+
</tr>
|
views/admin/import/options/_reimport_template.php
ADDED
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<tr>
|
2 |
+
<td colspan="3">
|
3 |
+
<fieldset class="optionsset">
|
4 |
+
<legend>Record Matching</legend>
|
5 |
+
<div class="input" style="margin-bottom:15px;">
|
6 |
+
<input type="radio" id="auto_matching_<?php echo $entry; ?>" class="switcher" name="duplicate_matching" value="auto" <?php echo 'manual' != $post['duplicate_matching'] ? 'checked="checked"': '' ?>/>
|
7 |
+
<label for="auto_matching_<?php echo $entry; ?>"><?php _e('Automatic Record Matching', 'pmxi_plugin' )?></label><br>
|
8 |
+
<div class="switcher-target-auto_matching_<?php echo $entry; ?>" style="padding-left:17px;">
|
9 |
+
<div class="input">
|
10 |
+
<label><?php _e("Unique key"); ?></label>
|
11 |
+
<input type="text" class="smaller-text" name="unique_key" style="width:300px;" value="<?php echo esc_attr($post['unique_key']) ?>" <?php echo ! ($this->isWizard && $update_previous->isEmpty()) ? 'disabled="disabled"' : '' ?>/>
|
12 |
+
<a href="#help" class="help" title="<?php _e('Specify something that is unique for all records. If posts are being updated and not just created during a brand new import, the problem is that the value of the unique key is not unique.', 'pmxi_plugin') ?>">?</a>
|
13 |
+
</div>
|
14 |
+
</div>
|
15 |
+
<input type="radio" id="manual_matching_<?php echo $entry; ?>" class="switcher" name="duplicate_matching" value="manual" <?php echo 'manual' == $post['duplicate_matching'] ? 'checked="checked"': '' ?>/>
|
16 |
+
<label for="manual_matching_<?php echo $entry; ?>"><?php _e('Manual Record Matching', 'pmxi_plugin' )?></label>
|
17 |
+
<a href="#help" class="help" title="<?php _e('This allows you to match records by something other than Unique Key.', 'pmxi_plugin') ?>">?</a>
|
18 |
+
<div class="switcher-target-manual_matching_<?php echo $entry; ?>" style="padding-left:17px;">
|
19 |
+
<div class="input">
|
20 |
+
<span style="vertical-align:middle"><?php _e('Match records based on...', 'pmxi_plugin') ?></span><br>
|
21 |
+
<input type="radio" id="duplicate_indicator_title_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="title" <?php echo 'title' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?>/>
|
22 |
+
<label for="duplicate_indicator_title_<?php echo $entry; ?>"><?php _e('title', 'pmxi_plugin' )?></label><br>
|
23 |
+
<input type="radio" id="duplicate_indicator_content_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="content" <?php echo 'content' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?>/>
|
24 |
+
<label for="duplicate_indicator_content_<?php echo $entry; ?>"><?php _e('content', 'pmxi_plugin' )?></label><br>
|
25 |
+
<input type="radio" id="duplicate_indicator_custom_field_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="custom field" <?php echo 'custom field' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?>/>
|
26 |
+
<label for="duplicate_indicator_custom_field_<?php echo $entry; ?>"><?php _e('custom field', 'pmxi_plugin' )?></label><br>
|
27 |
+
<span class="switcher-target-duplicate_indicator_custom_field_<?php echo $entry; ?>" style="vertical-align:middle" style="padding-left:17px;">
|
28 |
+
<?php _e('Name', 'pmxi_plugin') ?>
|
29 |
+
<input type="text" name="custom_duplicate_name" value="<?php echo esc_attr($post['custom_duplicate_name']) ?>" /><br>
|
30 |
+
<?php _e('Value', 'pmxi_plugin') ?>
|
31 |
+
<input type="text" name="custom_duplicate_value" value="<?php echo esc_attr($post['custom_duplicate_value']) ?>" />
|
32 |
+
</span>
|
33 |
+
</div>
|
34 |
+
</div>
|
35 |
+
</div>
|
36 |
+
<hr>
|
37 |
+
<div class="input">
|
38 |
+
<input type="hidden" name="not_create_records" value="0" />
|
39 |
+
<input type="checkbox" id="not_create_records_<?php echo $entry; ?>" name="not_create_records" value="1" <?php echo $post['not_create_records'] ? 'checked="checked"' : '' ?> />
|
40 |
+
<label for="not_create_records_<?php echo $entry; ?>"><?php _e('Do Not Add New Records', 'pmxi_plugin') ?></label>
|
41 |
+
</div>
|
42 |
+
<div class="input">
|
43 |
+
<input type="hidden" name="is_delete_missing" value="0" />
|
44 |
+
<input type="checkbox" id="is_delete_missing_<?php echo $entry; ?>" name="is_delete_missing" value="1" <?php echo $post['is_delete_missing'] ? 'checked="checked"': '' ?> class="switcher"/>
|
45 |
+
<label for="is_delete_missing_<?php echo $entry; ?>"><?php _e('Delete missing records', 'pmxi_plugin') ?></label>
|
46 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you want to delete posts from previous import operation which are not found among newly impoprted set.', 'pmxi_plugin') ?>">?</a>
|
47 |
+
</div>
|
48 |
+
<div class="switcher-target-is_delete_missing_<?php echo $entry; ?>" style="padding-left:17px;">
|
49 |
+
<div class="input">
|
50 |
+
<input type="hidden" name="is_keep_attachments" value="0" />
|
51 |
+
<input type="checkbox" id="is_keep_attachments_<?php echo $entry; ?>" name="is_keep_attachments" value="1" <?php echo $post['is_keep_attachments'] ? 'checked="checked"': '' ?> />
|
52 |
+
<label for="is_keep_attachments_<?php echo $entry; ?>"><?php _e('Keep attachments when records removed', 'pmxi_plugin') ?></label>
|
53 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you want attachments like featured image to be kept in media library after parent post or page is removed or replaced during reimport operation.', 'pmxi_plugin') ?>">?</a>
|
54 |
+
</div>
|
55 |
+
</div>
|
56 |
+
<div class="input">
|
57 |
+
<input type="radio" id="is_keep_former_posts_<?php echo $entry; ?>" name="is_keep_former_posts" value="yes" <?php echo "yes" == $post['is_keep_former_posts'] ? 'checked="checked"': '' ?> class="switcher" />
|
58 |
+
<label for="is_keep_former_posts_<?php echo $entry; ?>"><?php _e('Do not update already existing records', 'pmxi_plugin') ?></label> <br>
|
59 |
+
<input type="radio" id="is_not_keep_former_posts_<?php echo $entry; ?>" name="is_keep_former_posts" value="no" <?php echo "yes" != $post['is_keep_former_posts'] ? 'checked="checked"': '' ?> class="switcher" />
|
60 |
+
<label for="is_not_keep_former_posts_<?php echo $entry; ?>"><?php _e('Update existing records', 'pmxi_plugin') ?></label>
|
61 |
+
<div class="switcher-target-is_not_keep_former_posts_<?php echo $entry; ?>" style="padding-left:17px;">
|
62 |
+
<div class="input">
|
63 |
+
<input type="hidden" name="is_keep_status" value="0" />
|
64 |
+
<input type="checkbox" id="is_keep_status_<?php echo $entry; ?>" name="is_keep_status" value="1" <?php echo $post['is_keep_status'] ? 'checked="checked"': '' ?> />
|
65 |
+
<label for="is_keep_status_<?php echo $entry; ?>"><?php _e('Keep status', 'pmxi_plugin') ?></label>
|
66 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their publish status or being restored from Trash.', 'pmxi_plugin') ?>">?</a>
|
67 |
+
</div>
|
68 |
+
<div class="input">
|
69 |
+
<input type="hidden" name="is_keep_title" value="0" />
|
70 |
+
<input type="checkbox" id="is_keep_title_<?php echo $entry; ?>" name="is_keep_title" value="1" <?php echo $post['is_keep_title'] ? 'checked="checked"': '' ?> />
|
71 |
+
<label for="is_keep_title_<?php echo $entry; ?>"><?php _e('Keep title', 'pmxi_plugin') ?></label>
|
72 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their titles.', 'pmxi_plugin') ?>">?</a>
|
73 |
+
</div>
|
74 |
+
<div class="input">
|
75 |
+
<input type="hidden" name="is_keep_excerpt" value="0" />
|
76 |
+
<input type="checkbox" id="is_keep_excerpt_<?php echo $entry; ?>" name="is_keep_excerpt" value="1" <?php echo $post['is_keep_excerpt'] ? 'checked="checked"': '' ?> />
|
77 |
+
<label for="is_keep_excerpt_<?php echo $entry; ?>"><?php _e('Keep excerpt', 'pmxi_plugin') ?></label>
|
78 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their excerpts.', 'pmxi_plugin') ?>">?</a>
|
79 |
+
</div>
|
80 |
+
<div class="input">
|
81 |
+
<input type="hidden" name="is_keep_dates" value="0" />
|
82 |
+
<input type="checkbox" id="is_keep_dates_<?php echo $entry; ?>" name="is_keep_dates" value="1" <?php echo $post['is_keep_dates'] ? 'checked="checked"': '' ?> />
|
83 |
+
<label for="is_keep_dates_<?php echo $entry; ?>"><?php _e('Keep dates', 'pmxi_plugin') ?></label>
|
84 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their publish dates.', 'pmxi_plugin') ?>">?</a>
|
85 |
+
</div>
|
86 |
+
<div class="input">
|
87 |
+
<input type="hidden" name="is_keep_menu_order" value="0" />
|
88 |
+
<input type="checkbox" id="is_keep_menu_order_<?php echo $entry; ?>" name="is_keep_menu_order" value="1" <?php echo $post['is_keep_menu_order'] ? 'checked="checked"': '' ?> />
|
89 |
+
<label for="is_keep_menu_order_<?php echo $entry; ?>"><?php _e('Keep menu order', 'pmxi_plugin') ?></label>
|
90 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their menu order.', 'pmxi_plugin') ?>">?</a>
|
91 |
+
</div>
|
92 |
+
<div class="input">
|
93 |
+
<input type="hidden" name="is_keep_content" value="0" />
|
94 |
+
<input type="checkbox" id="is_keep_content_<?php echo $entry; ?>" name="is_keep_content" value="1" <?php echo $post['is_keep_content'] ? 'checked="checked"': '' ?> />
|
95 |
+
<label for="is_keep_content_<?php echo $entry; ?>"><?php _e('Keep content', 'pmxi_plugin') ?></label>
|
96 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their content.', 'pmxi_plugin') ?>">?</a>
|
97 |
+
</div>
|
98 |
+
<div class="input">
|
99 |
+
<input type="hidden" name="is_keep_categories" value="0" />
|
100 |
+
<input type="checkbox" id="is_keep_categories_<?php echo $entry; ?>" name="is_keep_categories" value="1" <?php echo $post['is_keep_categories'] ? 'checked="checked"': '' ?> />
|
101 |
+
<label for="is_keep_categories_<?php echo $entry; ?>"><?php _e('Keep categories, tags and taxonomies', 'pmxi_plugin') ?></label>
|
102 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their category, tag and custom taxonomies associations upon reimport.', 'pmxi_plugin') ?>">?</a>
|
103 |
+
</div>
|
104 |
+
<div class="input">
|
105 |
+
<input type="hidden" name="is_keep_images" value="0" />
|
106 |
+
<input type="checkbox" id="is_keep_images_<?php echo $entry; ?>" name="is_keep_images" value="1" <?php echo $post['is_keep_images'] ? 'checked="checked"': '' ?> />
|
107 |
+
<label for="is_keep_images_<?php echo $entry; ?>"><?php _e('Do not import images', 'pmxi_plugin') ?></label>
|
108 |
+
<a href="#help" class="help" title="<?php _e('This will keep the featured image if it exists, so you could modify the post image manually, and then do a reimport, and it would not overwrite the manually modified post image.', 'pmxi_plugin') ?>">?</a>
|
109 |
+
</div>
|
110 |
+
<div class="input">
|
111 |
+
<input type="hidden" name="no_create_featured_image" value="0" />
|
112 |
+
<input type="checkbox" id="no_create_featured_image_<?php echo $entry; ?>" name="no_create_featured_image" value="1" <?php echo $post['no_create_featured_image'] ? 'checked="checked"': '' ?> />
|
113 |
+
<label for="no_create_featured_image_<?php echo $entry; ?>"><?php _e('Only keep images for posts that already have images.', 'pmxi_plugin') ?></label>
|
114 |
+
<a href="#help" class="help" title="<?php _e('This option will keep images for posts that already have images, and import images for posts that do not already have images.', 'pmxi_plugin') ?>">?</a>
|
115 |
+
</div>
|
116 |
+
<div class="input">
|
117 |
+
<input type="hidden" name="keep_custom_fields" value="0" />
|
118 |
+
<input type="checkbox" id="keep_custom_fields_<?php echo $entry; ?>" name="keep_custom_fields" value="1" <?php echo $post['keep_custom_fields'] ? 'checked="checked"': '' ?> class="switcher switcher-reversed"/>
|
119 |
+
<label for="keep_custom_fields_<?php echo $entry; ?>"><?php _e('Keep custom fields', 'pmxi_plugin') ?></label>
|
120 |
+
<a href="#help" class="help" title="<?php _e('If Keep Custom Fields box is checked, it will keep all Custom Fields, and add any new Custom Fields specified in Custom Fields section, as long as they do not overwrite existing fields. If \'Only keep this Custom Fields\' is specified, it will only keep the specified fields.', 'pmxi_plugin') ?>">?</a>
|
121 |
+
</div>
|
122 |
+
<div class="switcher-target-keep_custom_fields_<?php echo $entry; ?>" style="padding-left:17px;">
|
123 |
+
<div class="input">
|
124 |
+
<label for="keep_custom_fields_specific"><?php _e('Only Keep These Custom Fields <small>(separate field names with commas)</small>', 'pmxi_plugin') ?></label>
|
125 |
+
<input type="text" id="keep_custom_fields_specific" name="keep_custom_fields_specific" style="width:100%;" value="<?php echo esc_attr($post['keep_custom_fields_specific']) ?>" />
|
126 |
+
</div>
|
127 |
+
</div>
|
128 |
+
</div>
|
129 |
+
</div>
|
130 |
+
</fieldset>
|
131 |
+
</td>
|
132 |
+
</tr>
|
views/admin/import/options/_taxonomies_template.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$post_taxonomies = array_diff_key(get_taxonomies_by_object_type(array($post_type), 'object'), array_flip(array('category', 'post_tag', 'post_format')));
|
3 |
+
if ( ! empty($post_taxonomies)): ?>
|
4 |
+
<tr>
|
5 |
+
<td colspan="3">
|
6 |
+
<fieldset class="optionsset">
|
7 |
+
<legend>Custom Taxonomies</legend>
|
8 |
+
<?php foreach ($post_taxonomies as $ctx): ?>
|
9 |
+
<table>
|
10 |
+
<tr>
|
11 |
+
<td>
|
12 |
+
<div class="post_taxonomy">
|
13 |
+
<div class="col2" style="width:35%;">
|
14 |
+
<nobr><?php echo $ctx->labels->name ?></nobr>
|
15 |
+
</div>
|
16 |
+
<div class="col2" style="width:65%;">
|
17 |
+
<ol class="sortable no-margin">
|
18 |
+
<?php if (!empty($post['post_taxonomies'][$ctx->name])):
|
19 |
+
$taxonomies_hierarchy = json_decode($post['post_taxonomies'][$ctx->name]);
|
20 |
+
if (!empty($taxonomies_hierarchy) and is_array($taxonomies_hierarchy)): $i = 0; foreach ($taxonomies_hierarchy as $cat) { $i++;
|
21 |
+
if (is_null($cat->parent_id) or empty($cat->parent_id))
|
22 |
+
{
|
23 |
+
?>
|
24 |
+
<li id="item_<?php echo $i; ?>">
|
25 |
+
<div class="drag-element"><input type="checkbox" class="assign_post" <?php if ($cat->assign): ?>checked="checked"<?php endif; ?>/><input type="text" class="widefat" value="<?php echo $cat->xpath; ?>"/></div><?php if ($i>1):?><a href="javascript:void(0);" class="icon-item remove-ico"></a><?php endif;?>
|
26 |
+
<?php echo reverse_taxonomies_html($taxonomies_hierarchy, $cat->item_id, $i); ?>
|
27 |
+
</li>
|
28 |
+
<?php
|
29 |
+
}
|
30 |
+
}; else:?>
|
31 |
+
<li id="item_1"><div class="drag-element"><input type="checkbox" class="assign_post" checked="checked"/><input type="text" class="widefat" value=""/></div></li>
|
32 |
+
<?php endif;
|
33 |
+
else: ?>
|
34 |
+
<li id="item_1"><div class="drag-element"><input type="checkbox" class="assign_post" checked="checked"/><input type="text" class="widefat" value=""/></div></li>
|
35 |
+
<?php endif; ?>
|
36 |
+
</ol>
|
37 |
+
<input type="hidden" class="hierarhy-output" name="post_taxonomies[<?php echo $ctx->name ?>]" value="<?php echo esc_attr($post['post_taxonomies'][$ctx->name]) ?>"/>
|
38 |
+
<div class="delim">
|
39 |
+
<label><?php _e('Separated by', 'pmxi_plugin'); ?></label>
|
40 |
+
<input type="text" class="small tax_delim" maxlength="1" value="<?php echo (!empty($ctx->delim)) ? $ctx->delim : ',' ?>" />
|
41 |
+
<a href="javascript:void(0);" class="icon-item add-new-ico">Add more</a>
|
42 |
+
</div>
|
43 |
+
</div>
|
44 |
+
</div>
|
45 |
+
</td>
|
46 |
+
</tr>
|
47 |
+
</table>
|
48 |
+
<?php endforeach; ?>
|
49 |
+
</fieldset>
|
50 |
+
</td>
|
51 |
+
</tr>
|
52 |
+
<?php endif;
|
53 |
+
?>
|
views/admin/import/process.php
CHANGED
@@ -1,31 +1,112 @@
|
|
1 |
<div class="inner-content">
|
2 |
<h2><?php _e('Import XML - <span id="status">Processing...</span>', 'pmxi_plugin') ?></h2>
|
3 |
-
<hr />
|
4 |
-
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<div class="inner-content">
|
2 |
<h2><?php _e('Import XML - <span id="status">Processing...</span>', 'pmxi_plugin') ?></h2>
|
3 |
+
<hr />
|
4 |
+
<p id="process_notice"><?php _e('Importing may take some time. Please do not close your browser or refresh the page until the process is complete.', 'pmxi_plugin') ?></p>
|
5 |
+
<?php _e('<div id="processbar"><div></div><span id="import_progress"><span id="left_progress">Time Elapsed <span id="then">00:00:00</span></span><span id="center_progress"> Created 0 / Updated 0 </span><span id="right_progress">0%</span></span></div>', 'pmxi_plugin'); ?>
|
6 |
+
<div id="logbar">
|
7 |
+
<a href="javascript:void(0);" id="view_log">View Log</a><span id="download_log_separator"> | </span> <a href="javascript:void(0);" id="download_log">Download Log</a>
|
8 |
+
<p>Warnings (<span id="warnings">0</span>), Errors (<span id="errors">0</span>)</p>
|
9 |
+
</div>
|
10 |
+
<fieldset id="logwrapper" <?php if ($_SESSION['pmxi_import']['large_file']): ?> style="display:none;" <?php endif; ?>>
|
11 |
+
<legend>Log</legend>
|
12 |
+
<div id="loglist">
|
13 |
+
|
14 |
+
</div>
|
15 |
+
</fieldset>
|
16 |
+
<a href="<?php echo add_query_arg(array('page' => 'pmxi-admin-manage'), remove_query_arg(array('id','page'), $this->baseUrl)); ?>" style="float:right; display:none;" id="import_finished"><?php _e('Manage Imports', 'pmxi_plugin') ?></a>
|
17 |
</div>
|
18 |
|
19 |
<script type="text/javascript">
|
20 |
//<![CDATA[
|
21 |
(function($){
|
22 |
$('#status').each(function () {
|
23 |
+
|
24 |
+
var then = $('#then');
|
25 |
+
start_date = moment().sod();
|
26 |
+
update = function(){
|
27 |
+
var duration = moment.duration({'seconds' : 1});
|
28 |
+
start_date.add(duration);
|
29 |
+
|
30 |
+
if ( ! $('#download_pmxi_log').length) then.html(start_date.format('HH:mm:ss'));
|
31 |
+
};
|
32 |
+
update();
|
33 |
+
setInterval(update, 1000);
|
34 |
+
|
35 |
var $this = $(this);
|
36 |
if ($this.html().match(/\.{3}$/)) {
|
37 |
var dots = 0;
|
38 |
var status = $this.html().replace(/\.{3}$/, '');
|
39 |
+
var interval ;
|
40 |
+
var odd = false;
|
41 |
interval = setInterval(function () {
|
42 |
+
var percents = $('.import_percent:last').html();
|
43 |
+
if ($this.html().match(new RegExp(status + '\\.{1,3}$', ''))) {
|
44 |
+
if (percents != null && percents != ''){
|
45 |
+
$this.html(status + '...'.substr(0, dots++ % 3 + 1));
|
46 |
+
var msg = $('.import_process_bar:last').html();
|
47 |
+
if (msg != undefined) $('#center_progress').html(msg);
|
48 |
+
$('#warnings').html($('.warnings_count:last').html());
|
49 |
+
$('#errors').html($('.errors_count:last').html());
|
50 |
+
$('#right_progress').html(((parseInt(percents) > 100 || percents == undefined) ? 100 : percents) + '%');
|
51 |
+
$('#processbar div').css({'width': ((parseInt(percents) > 100 || percents == undefined) ? 100 : percents) + '%'});
|
52 |
+
}
|
53 |
+
} else {
|
54 |
+
var msg = $('.import_process_bar:last').html();
|
55 |
+
if (msg != undefined) $('#center_progress').html(msg);
|
56 |
+
$('#right_progress').html(((parseInt(percents) > 100 || percents == undefined) ? 100 : percents) + '%');
|
57 |
+
$('#warnings').html($('.warnings_count:last').html());
|
58 |
+
$('#errors').html($('.errors_count:last').html());
|
59 |
+
$('#processbar div').css({'width': ((parseInt(percents) > 100 || percents == undefined) ? 100 : percents) + '%'});
|
60 |
+
$('#process_notice').hide();
|
61 |
+
$('#import_finished').show();
|
62 |
+
clearInterval(update);
|
63 |
+
clearInterval(interval);
|
64 |
+
}
|
65 |
+
if ($('#download_pmxi_log').length){
|
66 |
+
$('#download_log').attr('href', $('#download_pmxi_log').attr('href')).show();
|
67 |
+
$('#download_log_separator').show();
|
68 |
+
}
|
69 |
+
// fill log bar
|
70 |
+
$('.progress-msg').each(function(i){
|
71 |
+
if ( ! $(this).find('.import_process_bar').length){
|
72 |
+
<?php if ($_SESSION['pmxi_import']['large_file']): ?>
|
73 |
+
if ($('#loglist').find('p').length > 100) $('#loglist').html('');
|
74 |
+
<?php endif; ?>
|
75 |
+
$('#loglist').append('<p ' + ((odd) ? 'class="odd"' : 'class="even"') + '>' + $(this).html() + '</p>');
|
76 |
+
$('#loglist').animate({ scrollTop: $('#loglist').get(0).scrollHeight }, 0);
|
77 |
+
$(this).remove();
|
78 |
+
odd = !odd;
|
79 |
+
}
|
80 |
+
});
|
81 |
+
|
82 |
}, 1000);
|
83 |
+
$('#processbar').css({'visibility':'visible'});
|
84 |
}
|
85 |
});
|
86 |
window.onbeforeunload = function () {
|
87 |
return 'WARNING:\nImport process in under way, leaving the page will interrupt\nthe operation and most likely to cause leftovers in posts.';
|
88 |
+
};
|
89 |
})(jQuery);
|
90 |
+
|
91 |
//]]>
|
92 |
+
</script>
|
93 |
+
|
94 |
+
<?php if ($_SESSION['pmxi_import']['large_file']): ?>
|
95 |
+
|
96 |
+
<script type="text/javascript">
|
97 |
+
//<![CDATA[
|
98 |
+
(function($){
|
99 |
+
function parse_element(){
|
100 |
+
$.post('admin.php?page=pmxi-admin-import&action=process', {}, function (data) {
|
101 |
+
$('#loglist').append(data);
|
102 |
+
if ( ! $('#download_pmxi_log').length) parse_element();
|
103 |
+
}, 'html').fail(function() {
|
104 |
+
if ( ! $('#download_pmxi_log').length) parse_element();
|
105 |
+
});
|
106 |
+
}
|
107 |
+
parse_element();
|
108 |
+
})(jQuery);
|
109 |
+
//]]>
|
110 |
+
</script>
|
111 |
+
|
112 |
+
<?php endif; ?>
|
views/admin/import/tag.php
CHANGED
@@ -1,12 +1,15 @@
|
|
1 |
<div class="tag">
|
2 |
<input type="hidden" name="tagno" value="<?php echo $tagno ?>" />
|
3 |
<div class="title">
|
4 |
-
<?php printf(__('Record #<strong>%s</strong> out of <strong>%s</strong>', 'pmxi_plugin'), $tagno, $elements->length) ?>
|
5 |
<div class="navigation">
|
6 |
<?php if ($tagno > 1): ?><a href="#prev">⟨⟨</a><?php else: ?><span>⟨⟨</span><?php endif ?>
|
7 |
-
<?php if ($tagno < $elements->length): ?><a href="#next">⟩⟩</a><?php else: ?><span>⟩⟩</span><?php endif ?>
|
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>
|
1 |
<div class="tag">
|
2 |
<input type="hidden" name="tagno" value="<?php echo $tagno ?>" />
|
3 |
<div class="title">
|
4 |
+
<?php printf(__('Record #<strong>%s</strong> out of <strong>%s</strong>', 'pmxi_plugin'), $tagno, ( ! $_SESSION['pmxi_import']['large_file']) ? $elements->length : $_SESSION['pmxi_import']['count']); ?>
|
5 |
<div class="navigation">
|
6 |
<?php if ($tagno > 1): ?><a href="#prev">⟨⟨</a><?php else: ?><span>⟨⟨</span><?php endif ?>
|
7 |
+
<?php if ($tagno < $elements->length or ($_SESSION['pmxi_import']['large_file'] and $tagno < $_SESSION['pmxi_import']['count'])): ?><a href="#next">⟩⟩</a><?php else: ?><span>⟩⟩</span><?php endif ?>
|
8 |
</div>
|
9 |
</div>
|
10 |
+
<div class="clear"></div>
|
11 |
+
<div class="xml resetable"> <?php if (!empty($elements->length)) $this->render_xml_element(( ! $_SESSION['pmxi_import']['large_file']) ? $elements->item($tagno - 1) : $elements->item(0), true); ?></div>
|
12 |
+
<p class="xpath_help">
|
13 |
+
<?php _e('Operate on elements using your own PHP functions, use FOREACH loops, and more.<br />Read the <a href="http://www.wpallimport.com/portal/" target="_blank">documentation</a> to learn how.', 'pmxi_plugin') ?>
|
14 |
+
</p>
|
15 |
</div>
|
views/admin/import/template.php
CHANGED
@@ -1,81 +1,92 @@
|
|
1 |
<form class="template <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
<table class="layout">
|
3 |
-
|
4 |
-
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
<?php $templates = new PMXI_Template_List() ?>
|
7 |
-
<
|
|
|
8 |
<select name="load_template">
|
9 |
<option value=""><?php _e('Load Template...', 'pmxi_plugin') ?></option>
|
10 |
<?php foreach ($templates->getBy()->convertRecords() as $t): ?>
|
11 |
<option value="<?php echo $t->id ?>"><?php echo $t->name ?></option>
|
12 |
<?php endforeach ?>
|
13 |
-
</select
|
14 |
-
</span>
|
15 |
-
<?php if ($this->isWizard): ?>
|
16 |
-
<?php _e('Import XML/CSV - Step 3: Template Designer', 'pmxi_plugin') ?><br/><span class="taglines"><?php _e('arrange your data and design your posts', 'pmxi_plugin') ?></span>
|
17 |
-
<?php else: ?>
|
18 |
-
<?php _e('Edit Import Template', 'pmxi_plugin') ?>
|
19 |
-
<?php endif ?>
|
20 |
-
</h2>
|
21 |
-
<hr/>
|
22 |
-
|
23 |
-
<?php if ($this->errors->get_error_codes()): ?>
|
24 |
-
<?php $this->error() ?>
|
25 |
-
<?php endif ?>
|
26 |
-
|
27 |
-
<h3>Post Title</h3>
|
28 |
-
<div style="width:100%">
|
29 |
-
<input id="title" class="widefat" type="text" name="title" value="<?php echo esc_attr($post['title']) ?>" />
|
30 |
-
</div>
|
31 |
-
|
32 |
-
<h3>
|
33 |
-
<span class="header-option">
|
34 |
-
<input type="hidden" name="is_keep_linebreaks" value="0" />
|
35 |
-
<input type="checkbox" id="is_keep_linebreaks" name="is_keep_linebreaks" value="1" <?php echo $post['is_keep_linebreaks'] ? 'checked="checked"' : '' ?> />
|
36 |
-
<label for="is_keep_linebreaks"><?php _e('Keep line breaks from XML', 'pmxi_plugin') ?></label>
|
37 |
-
</span>
|
38 |
-
Post Content
|
39 |
-
</h3>
|
40 |
-
<div id="poststuff">
|
41 |
-
<div id="<?php echo user_can_richedit() ? 'postdivrich' : 'postdiv'; ?>" class="postarea">
|
42 |
-
|
43 |
-
<?php the_editor($post['content']) ?>
|
44 |
-
<table id="post-status-info" cellspacing="0">
|
45 |
-
<tbody>
|
46 |
-
<tr>
|
47 |
-
<td id="wp-word-count"></td>
|
48 |
-
<td class="autosave-info">
|
49 |
-
<span id="autosave"> </span>
|
50 |
-
</td>
|
51 |
-
</tr>
|
52 |
-
</tbody>
|
53 |
-
</table>
|
54 |
</div>
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
<input type="submit" class="button-primary" value="<?php _e('Edit', 'pmxi_plugin') ?>" />
|
68 |
-
<input type="text" name="name" title="<?php _e('Save Template As...', 'pmxi_plugin') ?>" style="vertical-align:middle" value="<?php echo esc_attr($post['name']) ?>" />
|
69 |
-
<?php endif ?>
|
70 |
-
</p>
|
71 |
-
</td>
|
72 |
-
<?php if ($this->isWizard or $this->isTemplateEdit): ?>
|
73 |
-
<td class="right">
|
74 |
-
<p><?php _e('Drag & Drop opening tag of an element for inserting corresponding XPath into template or title.', 'pmxi_plugin') ?></p>
|
75 |
-
<p><?php _e('<a href="http://www.wpallimport.com/template-syntax/" target="_blank">Template Syntax Documentation</a>', 'pmxi_plugin') ?> - includes information on looping and shortcodes.</p>
|
76 |
-
<?php $this->tag() ?>
|
77 |
</td>
|
78 |
-
|
79 |
-
|
|
|
|
|
|
|
|
|
80 |
</table>
|
81 |
</form>
|
1 |
<form class="template <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
|
2 |
+
<h2>
|
3 |
+
<?php if ($this->isWizard): ?>
|
4 |
+
<?php _e('Import XML/CSV - Step 3: Template Builder', 'pmxi_plugin') ?>
|
5 |
+
<?php else: ?>
|
6 |
+
<?php _e('Edit Import Template', 'pmxi_plugin') ?>
|
7 |
+
<?php endif ?>
|
8 |
+
</h2>
|
9 |
+
|
10 |
+
<?php if ($this->errors->get_error_codes()): ?>
|
11 |
+
<?php $this->error() ?>
|
12 |
+
<?php endif ?>
|
13 |
+
|
14 |
+
<h3>Drag-and-drop an element from the right to the left to build your template</h3>
|
15 |
+
|
16 |
<table class="layout">
|
17 |
+
<tr>
|
18 |
+
<td class="left">
|
19 |
+
<h3>Post Title</h3>
|
20 |
+
<div style="width:100%">
|
21 |
+
<input id="title" class="widefat" type="text" name="title" value="<?php echo esc_attr($post['title']) ?>" />
|
22 |
+
</div>
|
23 |
+
|
24 |
+
<h3>
|
25 |
+
Post Content
|
26 |
+
</h3>
|
27 |
+
<div id="poststuff">
|
28 |
+
<div id="<?php echo user_can_richedit() ? 'postdivrich' : 'postdiv'; ?>" class="postarea">
|
29 |
+
|
30 |
+
<?php the_editor($post['content']) ?>
|
31 |
+
<table id="post-status-info" cellspacing="0">
|
32 |
+
<tbody>
|
33 |
+
<tr>
|
34 |
+
<td id="wp-word-count"></td>
|
35 |
+
<td class="autosave-info">
|
36 |
+
<span id="autosave"> </span>
|
37 |
+
</td>
|
38 |
+
</tr>
|
39 |
+
</tbody>
|
40 |
+
</table>
|
41 |
+
</div>
|
42 |
+
</div>
|
43 |
+
<p>
|
44 |
+
<span class="header-option">
|
45 |
+
<input type="hidden" name="is_keep_linebreaks" value="0" />
|
46 |
+
<input type="checkbox" id="is_keep_linebreaks" name="is_keep_linebreaks" value="1" <?php echo $post['is_keep_linebreaks'] ? 'checked="checked"' : '' ?> style="position:relative; top:-3px;"/>
|
47 |
+
<label for="is_keep_linebreaks"><?php _e('Keep line breaks from XML', 'pmxi_plugin') ?></label> <br>
|
48 |
+
<input type="hidden" name="is_leave_html" value="0" />
|
49 |
+
<input type="checkbox" id="is_leave_html" name="is_leave_html" value="1" <?php echo $post['is_leave_html'] ? 'checked="checked"' : '' ?> style="position:relative; top:-3px;"/>
|
50 |
+
<label for="is_leave_html"><?php _e('Decode HTML entities with <b>html_entity_decode</b>', 'pmxi_plugin') ?></label><a class="help" href="#help" original-title="If HTML code is showing up in your posts, use this option. You can also use <br /><br /><i>[html_entity_decode({my/xpath})]</i><br /><br /> or <br /><br /><i>[htmlentities({my/xpath})]</i><br /><br /> to decode or encode HTML in your file.">?</a>
|
51 |
+
</span>
|
52 |
+
</p>
|
53 |
+
<hr>
|
54 |
+
<p style="clear:both;">
|
55 |
+
<?php wp_nonce_field('template', '_wpnonce_template'); ?>
|
56 |
+
<input type="hidden" name="is_submitted" value="1" />
|
57 |
+
<div class="input">
|
58 |
+
<input type="checkbox" id="save_template_as" name="save_template_as" value="1" <?php echo $post['save_template_as'] ? 'checked="checked"' : '' ?> style="position:relative; top:-2px;"/> <label for="save_template_as">Save template as:</label> <input type="text" name="name" title="<?php _e('Save Template As...', 'pmxi_plugin') ?>" style="vertical-align:middle; font-size:13px;" value="<?php echo esc_attr($post['name']) ?>" />
|
59 |
+
</div>
|
60 |
+
</p>
|
61 |
+
|
62 |
<?php $templates = new PMXI_Template_List() ?>
|
63 |
+
<div class="load-template">
|
64 |
+
<span>Load existing template: </span>
|
65 |
<select name="load_template">
|
66 |
<option value=""><?php _e('Load Template...', 'pmxi_plugin') ?></option>
|
67 |
<?php foreach ($templates->getBy()->convertRecords() as $t): ?>
|
68 |
<option value="<?php echo $t->id ?>"><?php echo $t->name ?></option>
|
69 |
<?php endforeach ?>
|
70 |
+
</select>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
</div>
|
72 |
+
|
73 |
+
<p>
|
74 |
+
<span class="submit-buttons" style="float:right;">
|
75 |
+
<?php if ($this->isWizard):?>
|
76 |
+
<a href="<?php echo add_query_arg('action', 'element', $this->baseUrl) ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
|
77 |
+
<?php else: ?>
|
78 |
+
<a href="<?php echo remove_query_arg('id', remove_query_arg('action', $this->baseUrl)); ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
|
79 |
+
<?php endif; ?>
|
80 |
+
<a href="#preview" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button preview" title="<?php _e('Preview Post', 'pmxi_plugin') ?>"><?php _e('Preview', 'pmxi_plugin') ?></a>
|
81 |
+
<input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e( ($this->isWizard) ? 'Next' : 'Update', 'pmxi_plugin') ?>" />
|
82 |
+
</span>
|
83 |
+
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
</td>
|
85 |
+
<?php if ($this->isWizard or $this->isTemplateEdit): ?>
|
86 |
+
<td class="right template-sidebar">
|
87 |
+
<?php $this->tag() ?>
|
88 |
+
</td>
|
89 |
+
<?php endif ?>
|
90 |
+
</tr>
|
91 |
</table>
|
92 |
</form>
|
views/admin/manage/delete.php
CHANGED
@@ -2,11 +2,13 @@
|
|
2 |
|
3 |
<form method="post">
|
4 |
<p><?php printf(__('Are you sure you want to delete <strong>%s</strong> import?', 'pmxi_plugin'), $item->name) ?></p>
|
5 |
-
<
|
|
|
|
|
6 |
<p class="submit">
|
7 |
<?php wp_nonce_field('delete-import', '_wpnonce_delete-import') ?>
|
8 |
<input type="hidden" name="is_confirmed" value="1" />
|
9 |
-
<input type="submit" class="button-
|
10 |
</p>
|
11 |
|
12 |
</form>
|
2 |
|
3 |
<form method="post">
|
4 |
<p><?php printf(__('Are you sure you want to delete <strong>%s</strong> import?', 'pmxi_plugin'), $item->name) ?></p>
|
5 |
+
<div class="input">
|
6 |
+
<input type="checkbox" id="is_delete_posts" name="is_delete_posts" /> <label for="is_delete_posts">Delete associated posts as well</label>
|
7 |
+
</div>
|
8 |
<p class="submit">
|
9 |
<?php wp_nonce_field('delete-import', '_wpnonce_delete-import') ?>
|
10 |
<input type="hidden" name="is_confirmed" value="1" />
|
11 |
+
<input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" value="Delete" />
|
12 |
</p>
|
13 |
|
14 |
</form>
|
views/admin/manage/index.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<h2>
|
2 |
<?php _e('Manage Imports', 'pmxi_plugin') ?>
|
3 |
|
4 |
-
<a href="<?php echo esc_url(add_query_arg(array('page' => 'pmxi-admin-import'), admin_url('admin.php'))) ?>" class="
|
5 |
</h2>
|
6 |
|
7 |
<?php if ($this->errors->get_error_codes()): ?>
|
@@ -21,16 +21,19 @@
|
|
21 |
// define the columns to display, the syntax is 'internal name' => 'display name'
|
22 |
$columns = array(
|
23 |
'id' => __('ID', 'pmxi_plugin'),
|
24 |
-
'name' => __('
|
25 |
-
'
|
26 |
-
'
|
27 |
-
'
|
|
|
|
|
|
|
28 |
);
|
29 |
?>
|
30 |
<form method="post" id="import-list" action="<?php echo remove_query_arg('pmxi_nt') ?>">
|
31 |
<input type="hidden" name="action" value="bulk" />
|
32 |
<?php wp_nonce_field('bulk-imports', '_wpnonce_bulk-imports') ?>
|
33 |
-
|
34 |
<div class="tablenav">
|
35 |
<div class="alignleft actions">
|
36 |
<select name="bulk-action">
|
@@ -53,7 +56,7 @@ $columns = array(
|
|
53 |
<?php endif ?>
|
54 |
</div>
|
55 |
<div class="clear"></div>
|
56 |
-
|
57 |
<table class="widefat pmxi-admin-imports">
|
58 |
<thead>
|
59 |
<tr>
|
@@ -67,7 +70,7 @@ $columns = array(
|
|
67 |
$order2 = 'ASC';
|
68 |
if ($order_by == $column_id)
|
69 |
$order2 = ($order == 'DESC') ? 'ASC' : 'DESC';
|
70 |
-
|
71 |
$column_link .= esc_url(add_query_arg(array('order' => $order2, 'order_by' => $column_id), $this->baseUrl));
|
72 |
$column_link .= "'>{$column_display_name}</a>";
|
73 |
$col_html .= '<th scope="col" class="column-' . $column_id . ' ' . ($order_by == $column_id ? $order : '') . '">' . $column_link . '</th>';
|
@@ -89,22 +92,8 @@ $columns = array(
|
|
89 |
<tr>
|
90 |
<td colspan="<?php echo count($columns) + 1 ?>"><?php _e('No previous imports found.', 'pmxi_plugin') ?></td>
|
91 |
</tr>
|
92 |
-
<?php else: ?>
|
93 |
-
<?php
|
94 |
-
$periods = array( // scheduling periods
|
95 |
-
'*/5 * * * *' => __('every 5 min'),
|
96 |
-
'*/10 * * * *' => __('every 10 min'),
|
97 |
-
'*/30 * * * *' => __('half-hourly'),
|
98 |
-
'0 * * * *' => __('hourly'),
|
99 |
-
'0 */4 * * *' => __('every 4 hours'),
|
100 |
-
'0 */12 * * *' => __('half-daily'),
|
101 |
-
'0 0 * * *' => __('daily'),
|
102 |
-
'0 0 * * 1' => __('weekly'),
|
103 |
-
'0 0 1 * 1' => __('monthly'),
|
104 |
-
);
|
105 |
-
$class = '';
|
106 |
-
?>
|
107 |
-
<?php foreach ($list as $item): ?>
|
108 |
<?php $class = ('alternate' == $class) ? '' : 'alternate'; ?>
|
109 |
<tr class="<?php echo $class; ?>" valign="middle">
|
110 |
<th scope="row" class="check-column">
|
@@ -119,11 +108,15 @@ $columns = array(
|
|
119 |
<?php echo $item['id'] ?>
|
120 |
</th>
|
121 |
<?php
|
122 |
-
break;
|
123 |
-
case '
|
124 |
?>
|
125 |
<td>
|
126 |
-
<?php
|
|
|
|
|
|
|
|
|
127 |
</td>
|
128 |
<?php
|
129 |
break;
|
@@ -138,22 +131,50 @@ $columns = array(
|
|
138 |
</td>
|
139 |
<?php
|
140 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
141 |
case 'name':
|
142 |
?>
|
143 |
<td>
|
144 |
-
<strong><?php echo $item['name'] ?></strong>
|
145 |
<?php if ($item['path']): ?>
|
146 |
-
|
147 |
<?php endif ?>
|
148 |
<div class="row-actions">
|
149 |
-
|
150 |
-
|
151 |
-
<?php
|
|
|
|
|
|
|
152 |
<span class="delete"><a class="delete" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'delete'), $this->baseUrl)) ?>"><?php _e('Delete', 'pmxi_plugin') ?></a></span>
|
|
|
|
|
|
|
153 |
</div>
|
154 |
</td>
|
155 |
<?php
|
156 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
case 'post_count':
|
158 |
?>
|
159 |
<td>
|
@@ -176,10 +197,10 @@ $columns = array(
|
|
176 |
<?php endif ?>
|
177 |
</tbody>
|
178 |
</table>
|
179 |
-
|
180 |
<div class="tablenav">
|
181 |
<?php if ($page_links): ?><div class="tablenav-pages"><?php echo $page_links_html ?></div><?php endif ?>
|
182 |
-
|
183 |
<div class="alignleft actions">
|
184 |
<select name="bulk-action2">
|
185 |
<option value="" selected="selected"><?php _e('Bulk Actions', 'pmxi_plugin') ?></option>
|
@@ -194,5 +215,5 @@ $columns = array(
|
|
194 |
</div>
|
195 |
</div>
|
196 |
<div class="clear"></div>
|
197 |
-
<a href="http://www.wpallimport.com/upgrade-to-pro?from=
|
198 |
</form>
|
1 |
<h2>
|
2 |
<?php _e('Manage Imports', 'pmxi_plugin') ?>
|
3 |
|
4 |
+
<a href="<?php echo esc_url(add_query_arg(array('page' => 'pmxi-admin-import'), admin_url('admin.php'))) ?>" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" style="font-size:15px; padding:10px 20px; text-decoration:none;"><?php echo esc_html_x('New Import', 'pmxi_plugin'); ?></a>
|
5 |
</h2>
|
6 |
|
7 |
<?php if ($this->errors->get_error_codes()): ?>
|
21 |
// define the columns to display, the syntax is 'internal name' => 'display name'
|
22 |
$columns = array(
|
23 |
'id' => __('ID', 'pmxi_plugin'),
|
24 |
+
'name' => __('File', 'pmxi_plugin'),
|
25 |
+
'xpath' => __('XPath', 'pmxi_plugin'),
|
26 |
+
'post_count' => __('Records', 'pmxi_plugin'),
|
27 |
+
'first_import' => __('First Import', 'pmxi_plugin'),
|
28 |
+
'registered_on' => __('Last Import', 'pmxi_plugin'),
|
29 |
+
/*'scheduled' => __('Reimport Schedule', 'pmxi_plugin'),
|
30 |
+
'next_import' => __('Next Import', 'pmxi_plugin'),*/
|
31 |
);
|
32 |
?>
|
33 |
<form method="post" id="import-list" action="<?php echo remove_query_arg('pmxi_nt') ?>">
|
34 |
<input type="hidden" name="action" value="bulk" />
|
35 |
<?php wp_nonce_field('bulk-imports', '_wpnonce_bulk-imports') ?>
|
36 |
+
|
37 |
<div class="tablenav">
|
38 |
<div class="alignleft actions">
|
39 |
<select name="bulk-action">
|
56 |
<?php endif ?>
|
57 |
</div>
|
58 |
<div class="clear"></div>
|
59 |
+
|
60 |
<table class="widefat pmxi-admin-imports">
|
61 |
<thead>
|
62 |
<tr>
|
70 |
$order2 = 'ASC';
|
71 |
if ($order_by == $column_id)
|
72 |
$order2 = ($order == 'DESC') ? 'ASC' : 'DESC';
|
73 |
+
|
74 |
$column_link .= esc_url(add_query_arg(array('order' => $order2, 'order_by' => $column_id), $this->baseUrl));
|
75 |
$column_link .= "'>{$column_display_name}</a>";
|
76 |
$col_html .= '<th scope="col" class="column-' . $column_id . ' ' . ($order_by == $column_id ? $order : '') . '">' . $column_link . '</th>';
|
92 |
<tr>
|
93 |
<td colspan="<?php echo count($columns) + 1 ?>"><?php _e('No previous imports found.', 'pmxi_plugin') ?></td>
|
94 |
</tr>
|
95 |
+
<?php else: ?>
|
96 |
+
<?php $class = ''; foreach ($list as $item): ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
<?php $class = ('alternate' == $class) ? '' : 'alternate'; ?>
|
98 |
<tr class="<?php echo $class; ?>" valign="middle">
|
99 |
<th scope="row" class="check-column">
|
108 |
<?php echo $item['id'] ?>
|
109 |
</th>
|
110 |
<?php
|
111 |
+
break;
|
112 |
+
case 'first_import':
|
113 |
?>
|
114 |
<td>
|
115 |
+
<?php if ('0000-00-00 00:00:00' == $item['first_import']): ?>
|
116 |
+
<em>never</em>
|
117 |
+
<?php else: ?>
|
118 |
+
<?php echo mysql2date(__('Y/m/d g:i a', 'pmxi_plugin'), $item['first_import']) ?>
|
119 |
+
<?php endif ?>
|
120 |
</td>
|
121 |
<?php
|
122 |
break;
|
131 |
</td>
|
132 |
<?php
|
133 |
break;
|
134 |
+
case 'next_import':
|
135 |
+
?>
|
136 |
+
<td>
|
137 |
+
<?php if ('0000-00-00 00:00:00' == $item['registered_on'] or empty($item['scheduled'])): ?>
|
138 |
+
<em>never</em>
|
139 |
+
<?php
|
140 |
+
else:
|
141 |
+
$task = new _PMXI_Import_Record_Cron_Parser($item['scheduled']);
|
142 |
+
$task_date = $task->getNextRunDate();
|
143 |
+
echo mysql2date(__('Y/m/d g:i a', 'pmxi_plugin'), $task_date->format('Y-m-d H:i:s'));
|
144 |
+
endif;
|
145 |
+
?>
|
146 |
+
</td>
|
147 |
+
<?php
|
148 |
+
break;
|
149 |
case 'name':
|
150 |
?>
|
151 |
<td>
|
152 |
+
<strong><?php echo (!empty($item['friendly_name'])) ? $item['friendly_name'] : $item['name']; ?></strong> <br>
|
153 |
<?php if ($item['path']): ?>
|
154 |
+
<em><?php echo str_replace("\\", '/', preg_replace('%^(\w+://[^:]+:)[^@]+@%', '$1*****@', $item['path'])); ?></em>
|
155 |
<?php endif ?>
|
156 |
<div class="row-actions">
|
157 |
+
|
158 |
+
<span class="edit"><a class="edit" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'edit'), $this->baseUrl)) ?>"><?php _e('Edit Template', 'pmxi_plugin') ?></a></span> |
|
159 |
+
<span class="edit"><a class="edit" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'options'), $this->baseUrl)) ?>"><?php _e('Edit Options', 'pmxi_plugin') ?></a></span> |
|
160 |
+
<span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'update'), $this->baseUrl)) ?>"><?php _e('Update', 'pmxi_plugin') ?></a></span> |
|
161 |
+
<span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('page' => 'pmxi-admin-import', 'id' => $item['id']), admin_url('admin.php'))) ?>"><?php _e('Use New File', 'pmxi_plugin') ?></a></span> |
|
162 |
+
<span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'log'), $this->baseUrl)) ?>"><?php _e('Download Log', 'pmxi_plugin') ?></a></span> |
|
163 |
<span class="delete"><a class="delete" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'delete'), $this->baseUrl)) ?>"><?php _e('Delete', 'pmxi_plugin') ?></a></span>
|
164 |
+
<?php if ( "Yes" == $item['large_import'] and $item['imported'] != $item['count']):?>
|
165 |
+
| <span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'update', 'type' => 'continue'), $this->baseUrl)) ?>"><?php _e('Continue import', 'pmxi_plugin') ?></a></span>
|
166 |
+
<?php endif; ?>
|
167 |
</div>
|
168 |
</td>
|
169 |
<?php
|
170 |
break;
|
171 |
+
case 'xpath':
|
172 |
+
?>
|
173 |
+
<td>
|
174 |
+
<?php echo $item['xpath'];?>
|
175 |
+
</td>
|
176 |
+
<?php
|
177 |
+
break;
|
178 |
case 'post_count':
|
179 |
?>
|
180 |
<td>
|
197 |
<?php endif ?>
|
198 |
</tbody>
|
199 |
</table>
|
200 |
+
|
201 |
<div class="tablenav">
|
202 |
<?php if ($page_links): ?><div class="tablenav-pages"><?php echo $page_links_html ?></div><?php endif ?>
|
203 |
+
|
204 |
<div class="alignleft actions">
|
205 |
<select name="bulk-action2">
|
206 |
<option value="" selected="selected"><?php _e('Bulk Actions', 'pmxi_plugin') ?></option>
|
215 |
</div>
|
216 |
</div>
|
217 |
<div class="clear"></div>
|
218 |
+
<a href="http://www.wpallimport.com/upgrade-to-pro?from=upi" target="_blank" class="upgrade_link">Upgrade to the paid edition of WP All Import to use this feature.</a>
|
219 |
</form>
|
views/admin/manage/update.php
CHANGED
@@ -12,7 +12,7 @@
|
|
12 |
<p class="submit">
|
13 |
<?php wp_nonce_field('update-import', '_wpnonce_update-import') ?>
|
14 |
<input type="hidden" name="is_confirmed" value="1" />
|
15 |
-
<input type="submit" class="button-
|
16 |
</p>
|
17 |
|
18 |
</form>
|
12 |
<p class="submit">
|
13 |
<?php wp_nonce_field('update-import', '_wpnonce_update-import') ?>
|
14 |
<input type="hidden" name="is_confirmed" value="1" />
|
15 |
+
<input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only ajax-update" value="Create Posts" />
|
16 |
</p>
|
17 |
|
18 |
</form>
|
views/admin/settings/index.php
CHANGED
@@ -37,10 +37,9 @@
|
|
37 |
<div><?php printf(__('post_max_size %s', 'pmxi_plugin'), ini_get('post_max_size')) ?></div>
|
38 |
<div><?php printf(__('max_execution_time %s', 'pmxi_plugin'), ini_get('max_execution_time')) ?></div>
|
39 |
<div><?php printf(__('max_input_time %s', 'pmxi_plugin'), ini_get('max_input_time')) ?></div>
|
40 |
-
<h3><?php _e('XML parsing filters', 'pmxi_plugin') ?></h3>
|
41 |
|
42 |
-
<
|
43 |
-
<
|
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" />
|
37 |
<div><?php printf(__('post_max_size %s', 'pmxi_plugin'), ini_get('post_max_size')) ?></div>
|
38 |
<div><?php printf(__('max_execution_time %s', 'pmxi_plugin'), ini_get('max_execution_time')) ?></div>
|
39 |
<div><?php printf(__('max_input_time %s', 'pmxi_plugin'), ini_get('max_input_time')) ?></div>
|
|
|
40 |
|
41 |
+
<h3><?php _e('Recurring & Scheduled Imports', 'pmxi_plugin') ?></h3>
|
42 |
+
<a href="http://www.wpallimport.com/upgrade-to-pro?from=upi" target="_blank" class="upgrade_link">Upgrade to the paid edition of WP All Import to use this feature.</a>
|
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" />
|