Version Description
Download this release
Release Info
Developer | acmethemes |
Plugin | Acme Demo Setup |
Version | 1.0.3 |
Comparing to | |
See all releases |
Version 1.0.3
- acme-demo-setup.php +44 -0
- inc/admin/upload.php +217 -0
- inc/assets/js/acme-demo-setup.js +49 -0
- inc/frameworks/customizer-export-import/class-cei-core.php +199 -0
- inc/frameworks/customizer-export-import/class-cei-option.php +28 -0
- inc/frameworks/widget-importer-exporter/import.php +244 -0
- inc/frameworks/widget-importer-exporter/widgets.php +33 -0
- inc/frameworks/wordpress-importer/parsers.php +689 -0
- inc/frameworks/wordpress-importer/wordpress-importer.php +1023 -0
- inc/hooks/after-demo-setup.php +80 -0
- inc/hooks/before-demo-setup.php +44 -0
- inc/info.txt +14 -0
- inc/init.php +21 -0
- readme.txt +107 -0
acme-demo-setup.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: Acme Demo Setup
|
4 |
+
Plugin URI:
|
5 |
+
Description: One click demo import
|
6 |
+
Version: 1.0.3
|
7 |
+
Author: Acme Themes
|
8 |
+
Author URI: https://www.acmethemes.com/
|
9 |
+
License: GPLv2 or later
|
10 |
+
*/
|
11 |
+
|
12 |
+
/*Make sure we don't expose any info if called directly*/
|
13 |
+
if ( !function_exists( 'add_action' ) ) {
|
14 |
+
echo 'Hi there! I\'m just a plugin, not much I can do when called directly.';
|
15 |
+
exit;
|
16 |
+
}
|
17 |
+
/*Define Constants for this plugin*/
|
18 |
+
define( 'ACME_DEMO_SETUP_VERSION', '1.0' );
|
19 |
+
define( 'ACME_DEMO_SETUP_PATH', plugin_dir_path( __FILE__ ) );
|
20 |
+
define( 'ACME_DEMO_SETUP_URL', plugin_dir_url( __FILE__ ) );
|
21 |
+
|
22 |
+
/*Now lets init the functionality of this plugin*/
|
23 |
+
require_once( ACME_DEMO_SETUP_PATH . '/inc/init.php' );
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Load plugin textdomain.
|
27 |
+
* see here https://ulrich.pogson.ch/load-theme-plugin-translations
|
28 |
+
*/
|
29 |
+
if ( ! function_exists( 'acme_demo_setup_load_textdomain' ) ) :
|
30 |
+
function acme_demo_setup_load_textdomain() {
|
31 |
+
|
32 |
+
$domain = 'acme-demo-setup';
|
33 |
+
$locale = apply_filters( 'plugin_locale', get_locale(), $domain );
|
34 |
+
|
35 |
+
// wp-content/languages/plugin-name/plugin-name-de_DE.mo
|
36 |
+
load_textdomain( 'acme-demo-setup', trailingslashit( WP_LANG_DIR ) . $domain . '/' . $domain . '-' . $locale . '.mo' );
|
37 |
+
|
38 |
+
// wp-content/plugins/plugin-name/languages/plugin-name-de_DE.mo
|
39 |
+
load_plugin_textdomain( 'acme-demo-setup', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
|
40 |
+
}
|
41 |
+
endif;
|
42 |
+
add_action( 'plugins_loaded', 'acme_demo_setup_load_textdomain' );
|
43 |
+
|
44 |
+
|
inc/admin/upload.php
ADDED
@@ -0,0 +1,217 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Acme Demo Setup
|
4 |
+
*
|
5 |
+
* @package Acme Themes
|
6 |
+
* @subpackage Acme Demo Setup
|
7 |
+
*/
|
8 |
+
if( !class_exists( 'Acme_Demo_Setup') ):
|
9 |
+
class Acme_Demo_Setup {
|
10 |
+
/**
|
11 |
+
* @return void
|
12 |
+
*/
|
13 |
+
function __construct( ) {
|
14 |
+
add_action( 'mime_types', array( $this, 'mime_types' ) );
|
15 |
+
add_action( 'admin_menu', array( $this, 'menu' ) );
|
16 |
+
/* enqueue script and style for about page */
|
17 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'style_and_scripts' ) );
|
18 |
+
/*ajax callback for demo content installation*/
|
19 |
+
add_action( 'wp_ajax_acme_demo_setup_ajax_setup', array( $this, 'handler' ) );
|
20 |
+
|
21 |
+
}
|
22 |
+
/**
|
23 |
+
* Load css and scripts for the about page
|
24 |
+
*/
|
25 |
+
public function style_and_scripts( $hook_suffix ) {
|
26 |
+
if ( 'appearance_page_acme-demo-setup' == $hook_suffix ) {
|
27 |
+
wp_enqueue_script( 'acme-demo-setup', ACME_DEMO_SETUP_URL.'inc/assets/js/acme-demo-setup.js', array( 'jquery' ) );
|
28 |
+
wp_localize_script( 'acme-demo-setup', 'acme_demo_setup_object', array(
|
29 |
+
'ajaxurl' => admin_url( 'admin-ajax.php' ),
|
30 |
+
'importing' => esc_html__('Importing','education-base'),
|
31 |
+
'imported' => esc_html__('Task Completed, view the log below','education-base')
|
32 |
+
) );
|
33 |
+
}
|
34 |
+
}
|
35 |
+
/**
|
36 |
+
* @return array
|
37 |
+
*/
|
38 |
+
function mime_types( $mimes ) {
|
39 |
+
$add_mimes = array(
|
40 |
+
'dat' => 'text/plain',
|
41 |
+
'xml' => 'application/xml',
|
42 |
+
'wie' => 'text/html'
|
43 |
+
);
|
44 |
+
|
45 |
+
return array_merge( $mimes, $add_mimes );
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Create admin pages in menu
|
50 |
+
*
|
51 |
+
* @return void
|
52 |
+
*/
|
53 |
+
function menu() {
|
54 |
+
add_theme_page( __( 'Acme Demo Setup', 'acme-demo-setup' ), __( 'Acme Demo Setup', 'acme-demo-setup' ), 'upload_files', 'acme-demo-setup', array( $this, 'screen' ) );
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* The Admin Screen
|
59 |
+
*/
|
60 |
+
function screen() {
|
61 |
+
echo '<div class="wrap">';
|
62 |
+
echo '<h2>' . __( 'Acme Demo Setup', 'acme-demo-setup' ) . '</h2>';
|
63 |
+
$this->handler();
|
64 |
+
$this->import_form();
|
65 |
+
echo '</div>';
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Handle the demo content upload and called to process
|
70 |
+
*
|
71 |
+
* @return string HTML Results or Error message
|
72 |
+
*/
|
73 |
+
function handler() {
|
74 |
+
$error = '';
|
75 |
+
$required_files = array();
|
76 |
+
if ( isset( $_FILES[ 'upload-zip-archive' ][ 'name' ] ) && ! empty( $_FILES[ 'upload-zip-archive' ][ 'name' ] ) ) {
|
77 |
+
|
78 |
+
/*check for security*/
|
79 |
+
if ( ! current_user_can( 'upload_files' ) ) {
|
80 |
+
wp_die( __( 'Sorry, you are not allowed to install demo on this site.', 'acme-demo-setup' ) );
|
81 |
+
}
|
82 |
+
check_admin_referer( 'acme-demo-setup' );
|
83 |
+
|
84 |
+
/*file process*/
|
85 |
+
esc_html_e('Uploading Zip...','acme-demo-import');
|
86 |
+
echo "<br />";
|
87 |
+
$upload_zip_archive = $_FILES[ 'upload-zip-archive' ];
|
88 |
+
WP_Filesystem();
|
89 |
+
global $wp_filesystem;
|
90 |
+
$upload_dir = wp_upload_dir();
|
91 |
+
$destination = $upload_dir['basedir'] . '/acme-demo-importer/';
|
92 |
+
|
93 |
+
/*the zip file shouldn't content greater than 3 files*/
|
94 |
+
$za = new ZipArchive();
|
95 |
+
$za->open( $upload_zip_archive['tmp_name'] );
|
96 |
+
$file_on_zip = $za->numFiles;
|
97 |
+
if( $file_on_zip > 3 ){
|
98 |
+
$error[] = __( "Invalid ZIP greater than 3 files" ,'acme-demo-importer');
|
99 |
+
}
|
100 |
+
|
101 |
+
/*unzip file*/
|
102 |
+
esc_html_e('Unzipping File...','acme-demo-import');
|
103 |
+
echo "<br />";
|
104 |
+
$unzipfile = unzip_file( $upload_zip_archive['tmp_name'], $destination);
|
105 |
+
if ( !$unzipfile ) {
|
106 |
+
$error[] = __( "Error on unzipping, Please try again" ,'acme-demo-importer');
|
107 |
+
}
|
108 |
+
|
109 |
+
/*get required file*/
|
110 |
+
$dirlist = $wp_filesystem->dirlist($destination);
|
111 |
+
foreach ( (array) $dirlist as $filename => $fileinfo ) {
|
112 |
+
$filetype = wp_check_filetype($filename);
|
113 |
+
if( 'xml' == $filetype['ext'] ){
|
114 |
+
$required_files['xml'] = $destination.$filename;
|
115 |
+
}
|
116 |
+
elseif ('wie' == $filetype['ext'] ){
|
117 |
+
$required_files['wie'] = $destination.$filename;
|
118 |
+
}
|
119 |
+
elseif ( 'dat' == $filetype['ext'] ){
|
120 |
+
$required_files['dat'] = $destination.$filename;
|
121 |
+
}
|
122 |
+
else{
|
123 |
+
$wp_filesystem->rmdir($destination, true );
|
124 |
+
$error[] = __( "Invalid ZIP destination file" ,'acme-demo-importer');
|
125 |
+
}
|
126 |
+
}
|
127 |
+
|
128 |
+
/*prepare array of files to import*/
|
129 |
+
if( !isset( $required_files['xml'] ) || empty( $required_files['xml'] )){
|
130 |
+
$error[] = __( "xml file not included" ,'acme-demo-importer');
|
131 |
+
|
132 |
+
}
|
133 |
+
if( !isset( $required_files['wie'] ) && empty( $required_files['wie'] )){
|
134 |
+
$error[] = __( "wie file not included" ,'acme-demo-importer');
|
135 |
+
|
136 |
+
}
|
137 |
+
if( !isset( $required_files['dat'] ) && empty( $required_files['dat'] )){
|
138 |
+
$error[] = __( "dat file not included" ,'acme-demo-importer');
|
139 |
+
}
|
140 |
+
if( is_array( $error ) && !empty( $error ) ){
|
141 |
+
foreach ( $error as $e ){
|
142 |
+
echo $e;
|
143 |
+
echo "<br />";
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
/*process import*/
|
148 |
+
$this->import( $required_files );
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
/*import */
|
153 |
+
function import( $required_files ){
|
154 |
+
/*before import*/
|
155 |
+
do_action( 'acme_demo_setup_before_import',$required_files );
|
156 |
+
|
157 |
+
/*xml demo import*/
|
158 |
+
if( isset( $required_files['xml'] ) && !empty( $required_files['xml'] ) ){
|
159 |
+
esc_html_e('Importing Demo Content...','acme-demo-import');
|
160 |
+
echo "<br /><br />";
|
161 |
+
|
162 |
+
// Try to update PHP memory limit (so that it does not run out of it).
|
163 |
+
ini_set( 'memory_limit', apply_filters( 'acme_demo_setup_memory_limit', '50M' ) );
|
164 |
+
|
165 |
+
$xml_import = new Acme_Demo_Setup_Wp_Import();
|
166 |
+
$xml_import->fetch_attachments = true;
|
167 |
+
set_time_limit(0);
|
168 |
+
$xml_import -> import( $required_files['xml'] );
|
169 |
+
}
|
170 |
+
|
171 |
+
/*customizer import*/
|
172 |
+
if( isset( $required_files['dat'] ) && !empty( $required_files['dat'] ) ){
|
173 |
+
esc_html_e('Importing Customizer Data...','acme-demo-import');
|
174 |
+
echo "<br /><br />";
|
175 |
+
|
176 |
+
$wie_import = new Acme_Demo_Setup_CEI_Core();
|
177 |
+
$wie_import -> _import( $required_files['dat'] );
|
178 |
+
}
|
179 |
+
|
180 |
+
/*widget import*/
|
181 |
+
if( isset( $required_files['dat'] ) && !empty( $required_files['dat'] ) ){
|
182 |
+
esc_html_e('Importing Widget Data...','acme-demo-import');
|
183 |
+
echo "<br /><br />";
|
184 |
+
|
185 |
+
acme_demo_setup_wie_process_import_file( $required_files['wie'] );
|
186 |
+
}
|
187 |
+
|
188 |
+
do_action( 'acme_demo_setup_after_import',$required_files );
|
189 |
+
|
190 |
+
printf( esc_html__('All Done Visit your %s site %s','acme-demo-import'),'<a href='.esc_url( get_home_url()).' target="_blank">','</a>' );
|
191 |
+
echo "<br /><br />";
|
192 |
+
|
193 |
+
exit;
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* The upload form
|
198 |
+
*
|
199 |
+
* @param null
|
200 |
+
*/
|
201 |
+
function import_form( ) {
|
202 |
+
echo '<form action="" method="post" enctype="multipart/form-data" id="acme-demo-setup-upload-zip-form">';
|
203 |
+
echo '<h3 class="media-title">'. __( 'Upload a zip file containing demo content', 'acme-demo-setup' ) .'</h3>';
|
204 |
+
echo '<p><input type="file" name="upload-zip-archive" id="upload-zip-archive" size="50" /></p>';
|
205 |
+
echo '<p>'. sprintf( __( 'Maximum upload file size: %s','acme-demo-setup' ), size_format( wp_max_upload_size() ) ) .'</p>';
|
206 |
+
wp_nonce_field( 'acme-demo-setup' );
|
207 |
+
submit_button( __( 'Upload and Import', 'acme-demo-setup' ) );
|
208 |
+
echo "<div id='at-demo-ajax-install-error' style='display: none;color: #d54e21'>".esc_html__('Select File and Try Again!','education-base')."</div>";
|
209 |
+
echo '</form>';
|
210 |
+
echo "<span id='at-demo-ajax-install-result-loading' class='button button-primary' style='display: none'>".esc_html__('Importing...','education-base')."</span>";
|
211 |
+
echo "<h4 id='at-demo-ajax-install-result-title' style='display: none'>".esc_html__('Task Completed, view the log below','education-base')."</h4>";
|
212 |
+
echo "<div id='at-demo-ajax-install-result'></div>";
|
213 |
+
}
|
214 |
+
|
215 |
+
}//end class
|
216 |
+
endif;
|
217 |
+
$Acme_Demo_Setup = new Acme_Demo_Setup();
|
inc/assets/js/acme-demo-setup.js
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(document).ready(function ($) {
|
2 |
+
$('#acme-demo-setup-upload-zip-form').submit(function (e) {
|
3 |
+
if( window.FormData === undefined ){
|
4 |
+
return true;
|
5 |
+
}
|
6 |
+
e.preventDefault();
|
7 |
+
var fd = new FormData();
|
8 |
+
var file = $(this).find('#upload-zip-archive');
|
9 |
+
if(!file.val()){
|
10 |
+
jQuery('#at-demo-ajax-install-error').show();
|
11 |
+
return false;
|
12 |
+
}
|
13 |
+
else{
|
14 |
+
jQuery('#at-demo-ajax-install-error').hide();
|
15 |
+
}
|
16 |
+
var _wpnonce = $(this).find('input[name=_wpnonce]');
|
17 |
+
var _wp_http_referer = $(this).find('input[name=_wp_http_referer]');
|
18 |
+
|
19 |
+
var individual_file = file[0].files[0];
|
20 |
+
|
21 |
+
fd.append("upload-zip-archive", individual_file);
|
22 |
+
fd.append('action', 'acme_demo_setup_ajax_setup');
|
23 |
+
fd.append('_wpnonce', _wpnonce.val());
|
24 |
+
fd.append('_wp_http_referer', _wp_http_referer.val());
|
25 |
+
|
26 |
+
jQuery.ajax({
|
27 |
+
type: 'POST',
|
28 |
+
url: acme_demo_setup_object.ajaxurl,
|
29 |
+
data: fd,
|
30 |
+
contentType: false,
|
31 |
+
processData: false,
|
32 |
+
beforeSend: function (data, settings) {
|
33 |
+
jQuery('#acme-demo-setup-upload-zip-form').remove();
|
34 |
+
jQuery('#at-demo-ajax-install-result-loading').show();
|
35 |
+
jQuery('#at-demo-ajax-install').html(acme_demo_setup_object.importing);
|
36 |
+
},
|
37 |
+
success : function (data) {
|
38 |
+
jQuery('#at-demo-ajax-install-result-loading').hide();
|
39 |
+
jQuery('#at-demo-ajax-install-result-title').show();
|
40 |
+
jQuery('#at-demo-ajax-install-result').html(data);
|
41 |
+
},
|
42 |
+
error : function (jqXHR, textStatus, errorThrown) {
|
43 |
+
console.log(jqXHR + " :: " + textStatus + " :: " + errorThrown);
|
44 |
+
}
|
45 |
+
});
|
46 |
+
return false;
|
47 |
+
});
|
48 |
+
|
49 |
+
});
|
inc/frameworks/customizer-export-import/class-cei-core.php
ADDED
@@ -0,0 +1,199 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The main export/import class from customizer-export-import.
|
4 |
+
* Renaming CEI_Core to Acme_Demo_Setup_CEI_Core
|
5 |
+
* @since 1.0.0
|
6 |
+
*/
|
7 |
+
final class Acme_Demo_Setup_CEI_Core {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* An array of core options that shouldn't be imported.
|
11 |
+
*
|
12 |
+
* @since 1.0.0
|
13 |
+
* @access private
|
14 |
+
* @var array $core_options
|
15 |
+
*/
|
16 |
+
static private $core_options = array(
|
17 |
+
'blogname',
|
18 |
+
'blogdescription',
|
19 |
+
'show_on_front',
|
20 |
+
'page_on_front',
|
21 |
+
'page_for_posts',
|
22 |
+
);
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Acme Customized Version
|
26 |
+
* Imports uploaded mods and calls WordPress core customize_save actions so
|
27 |
+
* themes that hook into them can act before mods are saved to the database.
|
28 |
+
*
|
29 |
+
* @since 1.0
|
30 |
+
* @access public
|
31 |
+
* @param object $wp_customize An instance of WP_Customize_Manager.
|
32 |
+
*/
|
33 |
+
function _import( $file_url ) {
|
34 |
+
$template = get_template();
|
35 |
+
|
36 |
+
WP_Filesystem();
|
37 |
+
|
38 |
+
// Setup global vars.
|
39 |
+
global $wp_filesystem;
|
40 |
+
global $wp_customize;
|
41 |
+
|
42 |
+
|
43 |
+
$raw = $wp_filesystem->get_contents( $file_url );
|
44 |
+
if ( $error = is_wp_error( $raw ) ) {
|
45 |
+
return $error;
|
46 |
+
}
|
47 |
+
|
48 |
+
$data = @unserialize( $raw );
|
49 |
+
|
50 |
+
// Data checks.
|
51 |
+
if ( 'array' != gettype( $data ) ) {
|
52 |
+
esc_html_e( 'Error importing settings! Please check that you uploaded a customizer export file.', 'acme-demo-setup' );
|
53 |
+
return;
|
54 |
+
}
|
55 |
+
if ( ! isset( $data['template'] ) || ! isset( $data['mods'] ) ) {
|
56 |
+
esc_html_e( 'Error importing settings! Please check that you uploaded a customizer export file.', 'acme-demo-setup' );
|
57 |
+
return;
|
58 |
+
}
|
59 |
+
if ( $data['template'] != $template ) {
|
60 |
+
esc_html_e( 'Error importing settings! The settings you uploaded are not for the current theme.', 'acme-demo-setup' );
|
61 |
+
return;
|
62 |
+
}
|
63 |
+
|
64 |
+
// Import images.
|
65 |
+
$data['mods'] = self::_import_images( $data['mods'] );
|
66 |
+
|
67 |
+
// Import custom options.
|
68 |
+
if ( isset( $data['options'] ) ) {
|
69 |
+
|
70 |
+
foreach ( $data['options'] as $option_key => $option_value ) {
|
71 |
+
|
72 |
+
$option = new Acme_Demo_Setup_CEI_Option( $wp_customize, $option_key, array(
|
73 |
+
'default' => '',
|
74 |
+
'type' => 'option',
|
75 |
+
'capability' => 'edit_theme_options'
|
76 |
+
) );
|
77 |
+
|
78 |
+
$option->import( $option_value );
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
// Call the customize_save action.
|
83 |
+
do_action( 'customize_save', $wp_customize );
|
84 |
+
|
85 |
+
// Loop through the mods.
|
86 |
+
foreach ( $data['mods'] as $key => $val ) {
|
87 |
+
|
88 |
+
// Call the customize_save_ dynamic action.
|
89 |
+
do_action( 'customize_save_' . $key, $wp_customize );
|
90 |
+
|
91 |
+
// Save the mod.
|
92 |
+
set_theme_mod( $key, $val );
|
93 |
+
}
|
94 |
+
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Imports images for settings saved as mods.
|
99 |
+
*
|
100 |
+
* @since 0.1
|
101 |
+
* @access private
|
102 |
+
* @param array $mods An array of customizer mods.
|
103 |
+
* @return array The mods array with any new import data.
|
104 |
+
*/
|
105 |
+
static private function _import_images( $mods )
|
106 |
+
{
|
107 |
+
foreach ( $mods as $key => $val ) {
|
108 |
+
|
109 |
+
if ( self::_is_image_url( $val ) ) {
|
110 |
+
|
111 |
+
$data = self::_sideload_image( $val );
|
112 |
+
|
113 |
+
if ( ! is_wp_error( $data ) ) {
|
114 |
+
|
115 |
+
$mods[ $key ] = $data->url;
|
116 |
+
|
117 |
+
// Handle header image controls.
|
118 |
+
if ( isset( $mods[ $key . '_data' ] ) ) {
|
119 |
+
$mods[ $key . '_data' ] = $data;
|
120 |
+
update_post_meta( $data->attachment_id, '_wp_attachment_is_custom_header', get_stylesheet() );
|
121 |
+
}
|
122 |
+
}
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
return $mods;
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Taken from the core media_sideload_image function and
|
131 |
+
* modified to return an array of data instead of html.
|
132 |
+
*
|
133 |
+
* @since 0.1
|
134 |
+
* @access private
|
135 |
+
* @param string $file The image file path.
|
136 |
+
* @return stdClass An array of image data.
|
137 |
+
*/
|
138 |
+
static private function _sideload_image( $file )
|
139 |
+
{
|
140 |
+
$data = new stdClass();
|
141 |
+
|
142 |
+
if ( ! function_exists( 'media_handle_sideload' ) ) {
|
143 |
+
require_once( ABSPATH . 'wp-admin/includes/media.php' );
|
144 |
+
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
145 |
+
require_once( ABSPATH . 'wp-admin/includes/image.php' );
|
146 |
+
}
|
147 |
+
if ( ! empty( $file ) ) {
|
148 |
+
|
149 |
+
// Set variables for storage, fix file filename for query strings.
|
150 |
+
preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches );
|
151 |
+
$file_array = array();
|
152 |
+
$file_array['name'] = basename( $matches[0] );
|
153 |
+
|
154 |
+
// Download file to temp location.
|
155 |
+
$file_array['tmp_name'] = download_url( $file );
|
156 |
+
|
157 |
+
// If error storing temporarily, return the error.
|
158 |
+
if ( is_wp_error( $file_array['tmp_name'] ) ) {
|
159 |
+
return $file_array['tmp_name'];
|
160 |
+
}
|
161 |
+
|
162 |
+
// Do the validation and storage stuff.
|
163 |
+
$id = media_handle_sideload( $file_array, 0 );
|
164 |
+
|
165 |
+
// If error storing permanently, unlink.
|
166 |
+
if ( is_wp_error( $id ) ) {
|
167 |
+
@unlink( $file_array['tmp_name'] );
|
168 |
+
return $id;
|
169 |
+
}
|
170 |
+
|
171 |
+
// Build the object to return.
|
172 |
+
$meta = wp_get_attachment_metadata( $id );
|
173 |
+
$data->attachment_id = $id;
|
174 |
+
$data->url = wp_get_attachment_url( $id );
|
175 |
+
$data->thumbnail_url = wp_get_attachment_thumb_url( $id );
|
176 |
+
$data->height = $meta['height'];
|
177 |
+
$data->width = $meta['width'];
|
178 |
+
}
|
179 |
+
|
180 |
+
return $data;
|
181 |
+
}
|
182 |
+
|
183 |
+
/**
|
184 |
+
* Checks to see whether a string is an image url or not.
|
185 |
+
*
|
186 |
+
* @since 0.1
|
187 |
+
* @access private
|
188 |
+
* @param string $string The string to check.
|
189 |
+
* @return bool Whether the string is an image url or not.
|
190 |
+
*/
|
191 |
+
static private function _is_image_url( $string = '' ){
|
192 |
+
if ( is_string( $string ) ) {
|
193 |
+
if ( preg_match( '/\.(jpg|jpeg|png|gif)/i', $string ) ) {
|
194 |
+
return true;
|
195 |
+
}
|
196 |
+
}
|
197 |
+
return false;
|
198 |
+
}
|
199 |
+
}
|
inc/frameworks/customizer-export-import/class-cei-option.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* A class that extends WP_Customize_Setting so we can access
|
4 |
+
* the protected updated method when importing options.
|
5 |
+
*
|
6 |
+
* @since 1.0.0
|
7 |
+
*
|
8 |
+
* Renaming CEI_Option to Acme_Demo_Setup_CEI_Option
|
9 |
+
*/
|
10 |
+
// Load WordPress Customize Setting Class.
|
11 |
+
if ( ! class_exists( 'WP_Customize_Setting' ) ) {
|
12 |
+
require_once( ABSPATH . WPINC . '/class-wp-customize-setting.php' );
|
13 |
+
}
|
14 |
+
|
15 |
+
final class Acme_Demo_Setup_CEI_Option extends WP_Customize_Setting {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Import an option value for this setting.
|
19 |
+
*
|
20 |
+
* @since 1.0.0
|
21 |
+
* @param mixed $value The option value.
|
22 |
+
* @return void
|
23 |
+
*/
|
24 |
+
public function import( $value )
|
25 |
+
{
|
26 |
+
$this->update( $value );
|
27 |
+
}
|
28 |
+
}
|
inc/frameworks/widget-importer-exporter/import.php
ADDED
@@ -0,0 +1,244 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Process import file
|
4 |
+
*
|
5 |
+
* This parses a file and triggers importation of its widgets.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @param string $file Path to .wie file uploaded
|
9 |
+
* @global string $wie_import_results
|
10 |
+
*
|
11 |
+
* Renaming wie_process_import_file to acme_demo_setup_wie_process_import_file
|
12 |
+
*/
|
13 |
+
function acme_demo_setup_wie_process_import_file( $file ) {
|
14 |
+
|
15 |
+
global $wie_import_results;
|
16 |
+
|
17 |
+
// File exists?
|
18 |
+
if ( ! file_exists( $file ) ) {
|
19 |
+
wp_die(
|
20 |
+
esc_html__( 'Import file could not be found. Please try again.', 'acme-demo-setup' ),
|
21 |
+
'',
|
22 |
+
array( 'back_link' => true )
|
23 |
+
);
|
24 |
+
}
|
25 |
+
|
26 |
+
// Get file contents and decode
|
27 |
+
$data = file_get_contents( $file );
|
28 |
+
$data = json_decode( $data );
|
29 |
+
|
30 |
+
// Import the widget data
|
31 |
+
// Make results available for display on import/export page
|
32 |
+
$wie_import_results = acme_demo_setup_wie_import_data( $data );
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Import widget JSON data
|
37 |
+
*
|
38 |
+
* @since 1.0.0
|
39 |
+
* @global array $wp_registered_sidebars
|
40 |
+
* @param object $data JSON widget data from .wie file
|
41 |
+
* @return array Results array
|
42 |
+
*/
|
43 |
+
function acme_demo_setup_wie_import_data( $data ) {
|
44 |
+
|
45 |
+
global $wp_registered_sidebars;
|
46 |
+
|
47 |
+
// Have valid data?
|
48 |
+
// If no data or could not decode
|
49 |
+
if ( empty( $data ) || ! is_object( $data ) ) {
|
50 |
+
wp_die(
|
51 |
+
esc_html__( 'Import data could not be read. Please try a different file.', 'acme-demo-setup' ),
|
52 |
+
'',
|
53 |
+
array( 'back_link' => true )
|
54 |
+
);
|
55 |
+
}
|
56 |
+
|
57 |
+
// Hook before import
|
58 |
+
do_action( 'wie_before_import' );
|
59 |
+
$data = apply_filters( 'wie_import_data', $data );
|
60 |
+
|
61 |
+
// Get all available widgets site supports
|
62 |
+
$available_widgets = acme_demo_setup_wie_available_widgets();
|
63 |
+
|
64 |
+
// Get all existing widget instances
|
65 |
+
$widget_instances = array();
|
66 |
+
foreach ( $available_widgets as $widget_data ) {
|
67 |
+
$widget_instances[$widget_data['id_base']] = get_option( 'widget_' . $widget_data['id_base'] );
|
68 |
+
}
|
69 |
+
|
70 |
+
// Begin results
|
71 |
+
$results = array();
|
72 |
+
|
73 |
+
// Loop import data's sidebars
|
74 |
+
foreach ( $data as $sidebar_id => $widgets ) {
|
75 |
+
|
76 |
+
// Skip inactive widgets
|
77 |
+
// (should not be in export file)
|
78 |
+
if ( 'wp_inactive_widgets' == $sidebar_id ) {
|
79 |
+
continue;
|
80 |
+
}
|
81 |
+
|
82 |
+
// Check if sidebar is available on this site
|
83 |
+
// Otherwise add widgets to inactive, and say so
|
84 |
+
if ( isset( $wp_registered_sidebars[$sidebar_id] ) ) {
|
85 |
+
$sidebar_available = true;
|
86 |
+
$use_sidebar_id = $sidebar_id;
|
87 |
+
$sidebar_message_type = 'success';
|
88 |
+
$sidebar_message = '';
|
89 |
+
} else {
|
90 |
+
$sidebar_available = false;
|
91 |
+
$use_sidebar_id = 'wp_inactive_widgets'; // add to inactive if sidebar does not exist in theme
|
92 |
+
$sidebar_message_type = 'error';
|
93 |
+
$sidebar_message = esc_html__( 'Widget area does not exist in theme (using Inactive)', 'acme-demo-setup' );
|
94 |
+
}
|
95 |
+
|
96 |
+
// Result for sidebar
|
97 |
+
$results[$sidebar_id]['name'] = ! empty( $wp_registered_sidebars[$sidebar_id]['name'] ) ? $wp_registered_sidebars[$sidebar_id]['name'] : $sidebar_id; // sidebar name if theme supports it; otherwise ID
|
98 |
+
$results[$sidebar_id]['message_type'] = $sidebar_message_type;
|
99 |
+
$results[$sidebar_id]['message'] = $sidebar_message;
|
100 |
+
$results[$sidebar_id]['widgets'] = array();
|
101 |
+
|
102 |
+
// Loop widgets
|
103 |
+
foreach ( $widgets as $widget_instance_id => $widget ) {
|
104 |
+
|
105 |
+
$fail = false;
|
106 |
+
|
107 |
+
// Get id_base (remove -# from end) and instance ID number
|
108 |
+
$id_base = preg_replace( '/-[0-9]+$/', '', $widget_instance_id );
|
109 |
+
$instance_id_number = str_replace( $id_base . '-', '', $widget_instance_id );
|
110 |
+
|
111 |
+
// Does site support this widget?
|
112 |
+
if ( ! $fail && ! isset( $available_widgets[$id_base] ) ) {
|
113 |
+
$fail = true;
|
114 |
+
$widget_message_type = 'error';
|
115 |
+
$widget_message = esc_html__( 'Site does not support widget', 'acme-demo-setup' ); // explain why widget not imported
|
116 |
+
}
|
117 |
+
|
118 |
+
// Filter to modify settings object before conversion to array and import
|
119 |
+
// Leave this filter here for backwards compatibility with manipulating objects (before conversion to array below)
|
120 |
+
// Ideally the newer wie_widget_settings_array below will be used instead of this
|
121 |
+
$widget = apply_filters( 'wie_widget_settings', $widget ); // object
|
122 |
+
|
123 |
+
// Convert multidimensional objects to multidimensional arrays
|
124 |
+
// Some plugins like Jetpack Widget Visibility store settings as multidimensional arrays
|
125 |
+
// Without this, they are imported as objects and cause fatal error on Widgets page
|
126 |
+
// If this creates problems for plugins that do actually intend settings in objects then may need to consider other approach: https://wordpress.org/support/topic/problem-with-array-of-arrays
|
127 |
+
// It is probably much more likely that arrays are used than objects, however
|
128 |
+
$widget = json_decode( wp_json_encode( $widget ), true );
|
129 |
+
|
130 |
+
// Filter to modify settings array
|
131 |
+
// This is preferred over the older wie_widget_settings filter above
|
132 |
+
// Do before identical check because changes may make it identical to end result (such as URL replacements)
|
133 |
+
$widget = apply_filters( 'wie_widget_settings_array', $widget );
|
134 |
+
|
135 |
+
// Does widget with identical settings already exist in same sidebar?
|
136 |
+
if ( ! $fail && isset( $widget_instances[$id_base] ) ) {
|
137 |
+
|
138 |
+
// Get existing widgets in this sidebar
|
139 |
+
$sidebars_widgets = get_option( 'sidebars_widgets' );
|
140 |
+
$sidebar_widgets = isset( $sidebars_widgets[$use_sidebar_id] ) ? $sidebars_widgets[$use_sidebar_id] : array(); // check Inactive if that's where will go
|
141 |
+
|
142 |
+
// Loop widgets with ID base
|
143 |
+
$single_widget_instances = ! empty( $widget_instances[$id_base] ) ? $widget_instances[$id_base] : array();
|
144 |
+
foreach ( $single_widget_instances as $check_id => $check_widget ) {
|
145 |
+
|
146 |
+
// Is widget in same sidebar and has identical settings?
|
147 |
+
if ( in_array( "$id_base-$check_id", $sidebar_widgets ) && (array) $widget == $check_widget ) {
|
148 |
+
|
149 |
+
$fail = true;
|
150 |
+
$widget_message_type = 'warning';
|
151 |
+
$widget_message = esc_html__( 'Widget already exists', 'acme-demo-setup' ); // explain why widget not imported
|
152 |
+
|
153 |
+
break;
|
154 |
+
|
155 |
+
}
|
156 |
+
|
157 |
+
}
|
158 |
+
|
159 |
+
}
|
160 |
+
|
161 |
+
// No failure
|
162 |
+
if ( ! $fail ) {
|
163 |
+
|
164 |
+
// Add widget instance
|
165 |
+
$single_widget_instances = get_option( 'widget_' . $id_base ); // all instances for that widget ID base, get fresh every time
|
166 |
+
$single_widget_instances = ! empty( $single_widget_instances ) ? $single_widget_instances : array( '_multiwidget' => 1 ); // start fresh if have to
|
167 |
+
$single_widget_instances[] = $widget; // add it
|
168 |
+
|
169 |
+
// Get the key it was given
|
170 |
+
end( $single_widget_instances );
|
171 |
+
$new_instance_id_number = key( $single_widget_instances );
|
172 |
+
|
173 |
+
// If key is 0, make it 1
|
174 |
+
// When 0, an issue can occur where adding a widget causes data from other widget to load, and the widget doesn't stick (reload wipes it)
|
175 |
+
if ( '0' === strval( $new_instance_id_number ) ) {
|
176 |
+
$new_instance_id_number = 1;
|
177 |
+
$single_widget_instances[$new_instance_id_number] = $single_widget_instances[0];
|
178 |
+
unset( $single_widget_instances[0] );
|
179 |
+
}
|
180 |
+
|
181 |
+
// Move _multiwidget to end of array for uniformity
|
182 |
+
if ( isset( $single_widget_instances['_multiwidget'] ) ) {
|
183 |
+
$multiwidget = $single_widget_instances['_multiwidget'];
|
184 |
+
unset( $single_widget_instances['_multiwidget'] );
|
185 |
+
$single_widget_instances['_multiwidget'] = $multiwidget;
|
186 |
+
}
|
187 |
+
|
188 |
+
// Update option with new widget
|
189 |
+
update_option( 'widget_' . $id_base, $single_widget_instances );
|
190 |
+
|
191 |
+
// Assign widget instance to sidebar
|
192 |
+
$sidebars_widgets = get_option( 'sidebars_widgets' ); // which sidebars have which widgets, get fresh every time
|
193 |
+
|
194 |
+
// Avoid rarely fatal error when the option is an empty string
|
195 |
+
// https://github.com/churchthemes/widget-importer-exporter/pull/11
|
196 |
+
if ( ! $sidebars_widgets ) {
|
197 |
+
$sidebars_widgets = array();
|
198 |
+
}
|
199 |
+
|
200 |
+
$new_instance_id = $id_base . '-' . $new_instance_id_number; // use ID number from new widget instance
|
201 |
+
$sidebars_widgets[$use_sidebar_id][] = $new_instance_id; // add new instance to sidebar
|
202 |
+
update_option( 'sidebars_widgets', $sidebars_widgets ); // save the amended data
|
203 |
+
|
204 |
+
// After widget import action
|
205 |
+
$after_widget_import = array(
|
206 |
+
'sidebar' => $use_sidebar_id,
|
207 |
+
'sidebar_old' => $sidebar_id,
|
208 |
+
'widget' => $widget,
|
209 |
+
'widget_type' => $id_base,
|
210 |
+
'widget_id' => $new_instance_id,
|
211 |
+
'widget_id_old' => $widget_instance_id,
|
212 |
+
'widget_id_num' => $new_instance_id_number,
|
213 |
+
'widget_id_num_old' => $instance_id_number
|
214 |
+
);
|
215 |
+
do_action( 'wie_after_widget_import', $after_widget_import );
|
216 |
+
|
217 |
+
// Success message
|
218 |
+
if ( $sidebar_available ) {
|
219 |
+
$widget_message_type = 'success';
|
220 |
+
$widget_message = esc_html__( 'Imported', 'acme-demo-setup' );
|
221 |
+
} else {
|
222 |
+
$widget_message_type = 'warning';
|
223 |
+
$widget_message = esc_html__( 'Imported to Inactive', 'acme-demo-setup' );
|
224 |
+
}
|
225 |
+
|
226 |
+
}
|
227 |
+
|
228 |
+
// Result for widget instance
|
229 |
+
$results[$sidebar_id]['widgets'][$widget_instance_id]['name'] = isset( $available_widgets[$id_base]['name'] ) ? $available_widgets[$id_base]['name'] : $id_base; // widget name or ID if name not available (not supported by site)
|
230 |
+
$results[$sidebar_id]['widgets'][$widget_instance_id]['title'] = ! empty( $widget['title'] ) ? $widget['title'] : esc_html__( 'No Title', 'acme-demo-setup' ); // show "No Title" if widget instance is untitled
|
231 |
+
$results[$sidebar_id]['widgets'][$widget_instance_id]['message_type'] = $widget_message_type;
|
232 |
+
$results[$sidebar_id]['widgets'][$widget_instance_id]['message'] = $widget_message;
|
233 |
+
|
234 |
+
}
|
235 |
+
|
236 |
+
}
|
237 |
+
|
238 |
+
// Hook after import
|
239 |
+
do_action( 'wie_after_import' );
|
240 |
+
|
241 |
+
// Return results
|
242 |
+
return apply_filters( 'wie_import_results', $results );
|
243 |
+
|
244 |
+
}
|
inc/frameworks/widget-importer-exporter/widgets.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Widget Functions
|
4 |
+
* @since 1.0.0
|
5 |
+
*/
|
6 |
+
|
7 |
+
// No direct access
|
8 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Available widgets
|
12 |
+
*
|
13 |
+
* Gather site's widgets into array with ID base, name, etc.
|
14 |
+
* Used by export and import functions.
|
15 |
+
*
|
16 |
+
* @since 0.4
|
17 |
+
* @global array $wp_registered_widget_updates
|
18 |
+
* @return array Widget information
|
19 |
+
*
|
20 |
+
* Remaning wie_available_widgets to acme_demo_setup_wie_available_widgets
|
21 |
+
*/
|
22 |
+
function acme_demo_setup_wie_available_widgets() {
|
23 |
+
global $wp_registered_widget_controls;
|
24 |
+
$widget_controls = $wp_registered_widget_controls;
|
25 |
+
$available_widgets = array();
|
26 |
+
foreach ( $widget_controls as $widget ) {
|
27 |
+
if ( ! empty( $widget['id_base'] ) && ! isset( $available_widgets[$widget['id_base']] ) ) { // no dupes
|
28 |
+
$available_widgets[$widget['id_base']]['id_base'] = $widget['id_base'];
|
29 |
+
$available_widgets[$widget['id_base']]['name'] = $widget['name'];
|
30 |
+
}
|
31 |
+
}
|
32 |
+
return apply_filters( 'acme_demo_setup_wie_available_widgets', $available_widgets );
|
33 |
+
}
|
inc/frameworks/wordpress-importer/parsers.php
ADDED
@@ -0,0 +1,689 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* WordPress eXtended RSS file parser implementations
|
4 |
+
*/
|
5 |
+
|
6 |
+
/**
|
7 |
+
* WordPress Importer class for managing parsing of WXR files.
|
8 |
+
* Renaming WXR_Parser to Acme_Demo_Setup_WXR_Parser
|
9 |
+
*/
|
10 |
+
class Acme_Demo_Setup_WXR_Parser {
|
11 |
+
function parse( $file ) {
|
12 |
+
// Attempt to use proper XML parsers first
|
13 |
+
if ( extension_loaded( 'simplexml' ) ) {
|
14 |
+
$parser = new Acme_Demo_Setup_WXR_Parser_SimpleXML;
|
15 |
+
$result = $parser->parse( $file );
|
16 |
+
|
17 |
+
// If SimpleXML succeeds or this is an invalid WXR file then return the results
|
18 |
+
if ( ! is_wp_error( $result ) || 'SimpleXML_parse_error' != $result->get_error_code() )
|
19 |
+
return $result;
|
20 |
+
} else if ( extension_loaded( 'xml' ) ) {
|
21 |
+
$parser = new Acme_Demo_Setup_WXR_Parser_XML;
|
22 |
+
$result = $parser->parse( $file );
|
23 |
+
|
24 |
+
// If XMLParser succeeds or this is an invalid WXR file then return the results
|
25 |
+
if ( ! is_wp_error( $result ) || 'XML_parse_error' != $result->get_error_code() )
|
26 |
+
return $result;
|
27 |
+
}
|
28 |
+
|
29 |
+
// We have a malformed XML file, so display the error and fallthrough to regex
|
30 |
+
if ( isset($result) && defined('IMPORT_DEBUG') && IMPORT_DEBUG ) {
|
31 |
+
echo '<pre>';
|
32 |
+
if ( 'SimpleXML_parse_error' == $result->get_error_code() ) {
|
33 |
+
foreach ( $result->get_error_data() as $error )
|
34 |
+
echo $error->line . ':' . $error->column . ' ' . esc_html( $error->message ) . "\n";
|
35 |
+
} else if ( 'XML_parse_error' == $result->get_error_code() ) {
|
36 |
+
$error = $result->get_error_data();
|
37 |
+
echo $error[0] . ':' . $error[1] . ' ' . esc_html( $error[2] );
|
38 |
+
}
|
39 |
+
echo '</pre>';
|
40 |
+
echo '<p><strong>' . __( 'There was an error when reading this WXR file', 'wordpress-importer' ) . '</strong><br />';
|
41 |
+
echo __( 'Details are shown above. The importer will now try again with a different parser...', 'wordpress-importer' ) . '</p>';
|
42 |
+
}
|
43 |
+
|
44 |
+
// use regular expressions if nothing else available or this is bad XML
|
45 |
+
$parser = new Acme_Demo_Setup_WXR_Parser_Regex;
|
46 |
+
return $parser->parse( $file );
|
47 |
+
}
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* WXR Parser that makes use of the SimpleXML PHP extension.
|
52 |
+
*/
|
53 |
+
class Acme_Demo_Setup_WXR_Parser_SimpleXML {
|
54 |
+
function parse( $file ) {
|
55 |
+
$authors = $posts = $categories = $tags = $terms = array();
|
56 |
+
|
57 |
+
$internal_errors = libxml_use_internal_errors(true);
|
58 |
+
|
59 |
+
$dom = new DOMDocument;
|
60 |
+
$old_value = null;
|
61 |
+
if ( function_exists( 'libxml_disable_entity_loader' ) ) {
|
62 |
+
$old_value = libxml_disable_entity_loader( true );
|
63 |
+
}
|
64 |
+
$success = $dom->loadXML( file_get_contents( $file ) );
|
65 |
+
if ( ! is_null( $old_value ) ) {
|
66 |
+
libxml_disable_entity_loader( $old_value );
|
67 |
+
}
|
68 |
+
|
69 |
+
if ( ! $success || isset( $dom->doctype ) ) {
|
70 |
+
return new WP_Error( 'SimpleXML_parse_error', __( 'There was an error when reading this WXR file', 'wordpress-importer' ), libxml_get_errors() );
|
71 |
+
}
|
72 |
+
|
73 |
+
$xml = simplexml_import_dom( $dom );
|
74 |
+
unset( $dom );
|
75 |
+
|
76 |
+
// halt if loading produces an error
|
77 |
+
if ( ! $xml )
|
78 |
+
return new WP_Error( 'SimpleXML_parse_error', __( 'There was an error when reading this WXR file', 'wordpress-importer' ), libxml_get_errors() );
|
79 |
+
|
80 |
+
$wxr_version = $xml->xpath('/rss/channel/wp:wxr_version');
|
81 |
+
if ( ! $wxr_version )
|
82 |
+
return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer' ) );
|
83 |
+
|
84 |
+
$wxr_version = (string) trim( $wxr_version[0] );
|
85 |
+
// confirm that we are dealing with the correct file format
|
86 |
+
if ( ! preg_match( '/^\d+\.\d+$/', $wxr_version ) )
|
87 |
+
return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer' ) );
|
88 |
+
|
89 |
+
$base_url = $xml->xpath('/rss/channel/wp:base_site_url');
|
90 |
+
$base_url = (string) trim( $base_url[0] );
|
91 |
+
|
92 |
+
$namespaces = $xml->getDocNamespaces();
|
93 |
+
if ( ! isset( $namespaces['wp'] ) )
|
94 |
+
$namespaces['wp'] = 'http://wordpress.org/export/1.1/';
|
95 |
+
if ( ! isset( $namespaces['excerpt'] ) )
|
96 |
+
$namespaces['excerpt'] = 'http://wordpress.org/export/1.1/excerpt/';
|
97 |
+
|
98 |
+
// grab authors
|
99 |
+
foreach ( $xml->xpath('/rss/channel/wp:author') as $author_arr ) {
|
100 |
+
$a = $author_arr->children( $namespaces['wp'] );
|
101 |
+
$login = (string) $a->author_login;
|
102 |
+
$authors[$login] = array(
|
103 |
+
'author_id' => (int) $a->author_id,
|
104 |
+
'author_login' => $login,
|
105 |
+
'author_email' => (string) $a->author_email,
|
106 |
+
'author_display_name' => (string) $a->author_display_name,
|
107 |
+
'author_first_name' => (string) $a->author_first_name,
|
108 |
+
'author_last_name' => (string) $a->author_last_name
|
109 |
+
);
|
110 |
+
}
|
111 |
+
|
112 |
+
// grab cats, tags and terms
|
113 |
+
foreach ( $xml->xpath('/rss/channel/wp:category') as $term_arr ) {
|
114 |
+
$t = $term_arr->children( $namespaces['wp'] );
|
115 |
+
$category = array(
|
116 |
+
'term_id' => (int) $t->term_id,
|
117 |
+
'category_nicename' => (string) $t->category_nicename,
|
118 |
+
'category_parent' => (string) $t->category_parent,
|
119 |
+
'cat_name' => (string) $t->cat_name,
|
120 |
+
'category_description' => (string) $t->category_description
|
121 |
+
);
|
122 |
+
|
123 |
+
foreach ( $t->termmeta as $meta ) {
|
124 |
+
$category['termmeta'][] = array(
|
125 |
+
'key' => (string) $meta->meta_key,
|
126 |
+
'value' => (string) $meta->meta_value
|
127 |
+
);
|
128 |
+
}
|
129 |
+
|
130 |
+
$categories[] = $category;
|
131 |
+
}
|
132 |
+
|
133 |
+
foreach ( $xml->xpath('/rss/channel/wp:tag') as $term_arr ) {
|
134 |
+
$t = $term_arr->children( $namespaces['wp'] );
|
135 |
+
$tag = array(
|
136 |
+
'term_id' => (int) $t->term_id,
|
137 |
+
'tag_slug' => (string) $t->tag_slug,
|
138 |
+
'tag_name' => (string) $t->tag_name,
|
139 |
+
'tag_description' => (string) $t->tag_description
|
140 |
+
);
|
141 |
+
|
142 |
+
foreach ( $t->termmeta as $meta ) {
|
143 |
+
$tag['termmeta'][] = array(
|
144 |
+
'key' => (string) $meta->meta_key,
|
145 |
+
'value' => (string) $meta->meta_value
|
146 |
+
);
|
147 |
+
}
|
148 |
+
|
149 |
+
$tags[] = $tag;
|
150 |
+
}
|
151 |
+
|
152 |
+
foreach ( $xml->xpath('/rss/channel/wp:term') as $term_arr ) {
|
153 |
+
$t = $term_arr->children( $namespaces['wp'] );
|
154 |
+
$term = array(
|
155 |
+
'term_id' => (int) $t->term_id,
|
156 |
+
'term_taxonomy' => (string) $t->term_taxonomy,
|
157 |
+
'slug' => (string) $t->term_slug,
|
158 |
+
'term_parent' => (string) $t->term_parent,
|
159 |
+
'term_name' => (string) $t->term_name,
|
160 |
+
'term_description' => (string) $t->term_description
|
161 |
+
);
|
162 |
+
|
163 |
+
foreach ( $t->termmeta as $meta ) {
|
164 |
+
$term['termmeta'][] = array(
|
165 |
+
'key' => (string) $meta->meta_key,
|
166 |
+
'value' => (string) $meta->meta_value
|
167 |
+
);
|
168 |
+
}
|
169 |
+
|
170 |
+
$terms[] = $term;
|
171 |
+
}
|
172 |
+
|
173 |
+
// grab posts
|
174 |
+
foreach ( $xml->channel->item as $item ) {
|
175 |
+
$post = array(
|
176 |
+
'post_title' => (string) $item->title,
|
177 |
+
'guid' => (string) $item->guid,
|
178 |
+
);
|
179 |
+
|
180 |
+
$dc = $item->children( 'http://purl.org/dc/elements/1.1/' );
|
181 |
+
$post['post_author'] = (string) $dc->creator;
|
182 |
+
|
183 |
+
$content = $item->children( 'http://purl.org/rss/1.0/modules/content/' );
|
184 |
+
$excerpt = $item->children( $namespaces['excerpt'] );
|
185 |
+
$post['post_content'] = (string) $content->encoded;
|
186 |
+
$post['post_excerpt'] = (string) $excerpt->encoded;
|
187 |
+
|
188 |
+
$wp = $item->children( $namespaces['wp'] );
|
189 |
+
$post['post_id'] = (int) $wp->post_id;
|
190 |
+
$post['post_date'] = (string) $wp->post_date;
|
191 |
+
$post['post_date_gmt'] = (string) $wp->post_date_gmt;
|
192 |
+
$post['comment_status'] = (string) $wp->comment_status;
|
193 |
+
$post['ping_status'] = (string) $wp->ping_status;
|
194 |
+
$post['post_name'] = (string) $wp->post_name;
|
195 |
+
$post['status'] = (string) $wp->status;
|
196 |
+
$post['post_parent'] = (int) $wp->post_parent;
|
197 |
+
$post['menu_order'] = (int) $wp->menu_order;
|
198 |
+
$post['post_type'] = (string) $wp->post_type;
|
199 |
+
$post['post_password'] = (string) $wp->post_password;
|
200 |
+
$post['is_sticky'] = (int) $wp->is_sticky;
|
201 |
+
|
202 |
+
if ( isset($wp->attachment_url) )
|
203 |
+
$post['attachment_url'] = (string) $wp->attachment_url;
|
204 |
+
|
205 |
+
foreach ( $item->category as $c ) {
|
206 |
+
$att = $c->attributes();
|
207 |
+
if ( isset( $att['nicename'] ) )
|
208 |
+
$post['terms'][] = array(
|
209 |
+
'name' => (string) $c,
|
210 |
+
'slug' => (string) $att['nicename'],
|
211 |
+
'domain' => (string) $att['domain']
|
212 |
+
);
|
213 |
+
}
|
214 |
+
|
215 |
+
foreach ( $wp->postmeta as $meta ) {
|
216 |
+
$post['postmeta'][] = array(
|
217 |
+
'key' => (string) $meta->meta_key,
|
218 |
+
'value' => (string) $meta->meta_value
|
219 |
+
);
|
220 |
+
}
|
221 |
+
|
222 |
+
foreach ( $wp->comment as $comment ) {
|
223 |
+
$meta = array();
|
224 |
+
if ( isset( $comment->commentmeta ) ) {
|
225 |
+
foreach ( $comment->commentmeta as $m ) {
|
226 |
+
$meta[] = array(
|
227 |
+
'key' => (string) $m->meta_key,
|
228 |
+
'value' => (string) $m->meta_value
|
229 |
+
);
|
230 |
+
}
|
231 |
+
}
|
232 |
+
|
233 |
+
$post['comments'][] = array(
|
234 |
+
'comment_id' => (int) $comment->comment_id,
|
235 |
+
'comment_author' => (string) $comment->comment_author,
|
236 |
+
'comment_author_email' => (string) $comment->comment_author_email,
|
237 |
+
'comment_author_IP' => (string) $comment->comment_author_IP,
|
238 |
+
'comment_author_url' => (string) $comment->comment_author_url,
|
239 |
+
'comment_date' => (string) $comment->comment_date,
|
240 |
+
'comment_date_gmt' => (string) $comment->comment_date_gmt,
|
241 |
+
'comment_content' => (string) $comment->comment_content,
|
242 |
+
'comment_approved' => (string) $comment->comment_approved,
|
243 |
+
'comment_type' => (string) $comment->comment_type,
|
244 |
+
'comment_parent' => (string) $comment->comment_parent,
|
245 |
+
'comment_user_id' => (int) $comment->comment_user_id,
|
246 |
+
'commentmeta' => $meta,
|
247 |
+
);
|
248 |
+
}
|
249 |
+
|
250 |
+
$posts[] = $post;
|
251 |
+
}
|
252 |
+
|
253 |
+
return array(
|
254 |
+
'authors' => $authors,
|
255 |
+
'posts' => $posts,
|
256 |
+
'categories' => $categories,
|
257 |
+
'tags' => $tags,
|
258 |
+
'terms' => $terms,
|
259 |
+
'base_url' => $base_url,
|
260 |
+
'version' => $wxr_version
|
261 |
+
);
|
262 |
+
}
|
263 |
+
}
|
264 |
+
|
265 |
+
/**
|
266 |
+
* WXR Parser that makes use of the XML Parser PHP extension.
|
267 |
+
*/
|
268 |
+
class Acme_Demo_Setup_WXR_Parser_XML {
|
269 |
+
var $wp_tags = array(
|
270 |
+
'wp:post_id', 'wp:post_date', 'wp:post_date_gmt', 'wp:comment_status', 'wp:ping_status', 'wp:attachment_url',
|
271 |
+
'wp:status', 'wp:post_name', 'wp:post_parent', 'wp:menu_order', 'wp:post_type', 'wp:post_password',
|
272 |
+
'wp:is_sticky', 'wp:term_id', 'wp:category_nicename', 'wp:category_parent', 'wp:cat_name', 'wp:category_description',
|
273 |
+
'wp:tag_slug', 'wp:tag_name', 'wp:tag_description', 'wp:term_taxonomy', 'wp:term_parent',
|
274 |
+
'wp:term_name', 'wp:term_description', 'wp:author_id', 'wp:author_login', 'wp:author_email', 'wp:author_display_name',
|
275 |
+
'wp:author_first_name', 'wp:author_last_name',
|
276 |
+
);
|
277 |
+
var $wp_sub_tags = array(
|
278 |
+
'wp:comment_id', 'wp:comment_author', 'wp:comment_author_email', 'wp:comment_author_url',
|
279 |
+
'wp:comment_author_IP', 'wp:comment_date', 'wp:comment_date_gmt', 'wp:comment_content',
|
280 |
+
'wp:comment_approved', 'wp:comment_type', 'wp:comment_parent', 'wp:comment_user_id',
|
281 |
+
);
|
282 |
+
|
283 |
+
function parse( $file ) {
|
284 |
+
$this->wxr_version = $this->in_post = $this->cdata = $this->data = $this->sub_data = $this->in_tag = $this->in_sub_tag = false;
|
285 |
+
$this->authors = $this->posts = $this->term = $this->category = $this->tag = array();
|
286 |
+
|
287 |
+
$xml = xml_parser_create( 'UTF-8' );
|
288 |
+
xml_parser_set_option( $xml, XML_OPTION_SKIP_WHITE, 1 );
|
289 |
+
xml_parser_set_option( $xml, XML_OPTION_CASE_FOLDING, 0 );
|
290 |
+
xml_set_object( $xml, $this );
|
291 |
+
xml_set_character_data_handler( $xml, 'cdata' );
|
292 |
+
xml_set_element_handler( $xml, 'tag_open', 'tag_close' );
|
293 |
+
|
294 |
+
if ( ! xml_parse( $xml, file_get_contents( $file ), true ) ) {
|
295 |
+
$current_line = xml_get_current_line_number( $xml );
|
296 |
+
$current_column = xml_get_current_column_number( $xml );
|
297 |
+
$error_code = xml_get_error_code( $xml );
|
298 |
+
$error_string = xml_error_string( $error_code );
|
299 |
+
return new WP_Error( 'XML_parse_error', 'There was an error when reading this WXR file', array( $current_line, $current_column, $error_string ) );
|
300 |
+
}
|
301 |
+
xml_parser_free( $xml );
|
302 |
+
|
303 |
+
if ( ! preg_match( '/^\d+\.\d+$/', $this->wxr_version ) )
|
304 |
+
return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer' ) );
|
305 |
+
|
306 |
+
return array(
|
307 |
+
'authors' => $this->authors,
|
308 |
+
'posts' => $this->posts,
|
309 |
+
'categories' => $this->category,
|
310 |
+
'tags' => $this->tag,
|
311 |
+
'terms' => $this->term,
|
312 |
+
'base_url' => $this->base_url,
|
313 |
+
'version' => $this->wxr_version
|
314 |
+
);
|
315 |
+
}
|
316 |
+
|
317 |
+
function tag_open( $parse, $tag, $attr ) {
|
318 |
+
if ( in_array( $tag, $this->wp_tags ) ) {
|
319 |
+
$this->in_tag = substr( $tag, 3 );
|
320 |
+
return;
|
321 |
+
}
|
322 |
+
|
323 |
+
if ( in_array( $tag, $this->wp_sub_tags ) ) {
|
324 |
+
$this->in_sub_tag = substr( $tag, 3 );
|
325 |
+
return;
|
326 |
+
}
|
327 |
+
|
328 |
+
switch ( $tag ) {
|
329 |
+
case 'category':
|
330 |
+
if ( isset($attr['domain'], $attr['nicename']) ) {
|
331 |
+
$this->sub_data['domain'] = $attr['domain'];
|
332 |
+
$this->sub_data['slug'] = $attr['nicename'];
|
333 |
+
}
|
334 |
+
break;
|
335 |
+
case 'item': $this->in_post = true;
|
336 |
+
case 'title': if ( $this->in_post ) $this->in_tag = 'post_title'; break;
|
337 |
+
case 'guid': $this->in_tag = 'guid'; break;
|
338 |
+
case 'dc:creator': $this->in_tag = 'post_author'; break;
|
339 |
+
case 'content:encoded': $this->in_tag = 'post_content'; break;
|
340 |
+
case 'excerpt:encoded': $this->in_tag = 'post_excerpt'; break;
|
341 |
+
|
342 |
+
case 'wp:term_slug': $this->in_tag = 'slug'; break;
|
343 |
+
case 'wp:meta_key': $this->in_sub_tag = 'key'; break;
|
344 |
+
case 'wp:meta_value': $this->in_sub_tag = 'value'; break;
|
345 |
+
}
|
346 |
+
}
|
347 |
+
|
348 |
+
function cdata( $parser, $cdata ) {
|
349 |
+
if ( ! trim( $cdata ) )
|
350 |
+
return;
|
351 |
+
|
352 |
+
if ( false !== $this->in_tag || false !== $this->in_sub_tag ) {
|
353 |
+
$this->cdata .= $cdata;
|
354 |
+
} else {
|
355 |
+
$this->cdata .= trim( $cdata );
|
356 |
+
}
|
357 |
+
}
|
358 |
+
|
359 |
+
function tag_close( $parser, $tag ) {
|
360 |
+
switch ( $tag ) {
|
361 |
+
case 'wp:comment':
|
362 |
+
unset( $this->sub_data['key'], $this->sub_data['value'] ); // remove meta sub_data
|
363 |
+
if ( ! empty( $this->sub_data ) )
|
364 |
+
$this->data['comments'][] = $this->sub_data;
|
365 |
+
$this->sub_data = false;
|
366 |
+
break;
|
367 |
+
case 'wp:commentmeta':
|
368 |
+
$this->sub_data['commentmeta'][] = array(
|
369 |
+
'key' => $this->sub_data['key'],
|
370 |
+
'value' => $this->sub_data['value']
|
371 |
+
);
|
372 |
+
break;
|
373 |
+
case 'category':
|
374 |
+
if ( ! empty( $this->sub_data ) ) {
|
375 |
+
$this->sub_data['name'] = $this->cdata;
|
376 |
+
$this->data['terms'][] = $this->sub_data;
|
377 |
+
}
|
378 |
+
$this->sub_data = false;
|
379 |
+
break;
|
380 |
+
case 'wp:postmeta':
|
381 |
+
if ( ! empty( $this->sub_data ) )
|
382 |
+
$this->data['postmeta'][] = $this->sub_data;
|
383 |
+
$this->sub_data = false;
|
384 |
+
break;
|
385 |
+
case 'item':
|
386 |
+
$this->posts[] = $this->data;
|
387 |
+
$this->data = false;
|
388 |
+
break;
|
389 |
+
case 'wp:category':
|
390 |
+
case 'wp:tag':
|
391 |
+
case 'wp:term':
|
392 |
+
$n = substr( $tag, 3 );
|
393 |