├── assets ├── css │ └── dt-importer.css ├── img │ └── screenshot.png └── js │ └── dt-importer.js ├── classes ├── abstract.class.php ├── importer.class.php ├── parsers.php └── wordpress-importer.php ├── demos ├── demo-1 │ ├── content.xml │ ├── options.txt │ └── screenshot.png ├── demo-2 │ ├── content.xml │ └── screenshot.png ├── demo-3 │ ├── content.xml │ └── screenshot.png └── demo-4 │ ├── content.xml │ └── screenshot.png ├── init.php ├── licence.txt └── readme.md /assets/css/dt-importer.css: -------------------------------------------------------------------------------- 1 | .dt-importer {} 2 | .dt-demo-browser {} 3 | .dt-demo-browser .dt-demo-item { 4 | position: relative; 5 | width: 350px; 6 | height: 360px; 7 | float: left; 8 | border: 1px solid #dedede; 9 | background: #FFF; 10 | margin: 10px; 11 | box-shadow: 0px 0px 7px 1px rgba(0, 0, 0, 0.06); 12 | overflow: hidden; 13 | } 14 | .dt-demo-item > .dt-demo-screenshot { 15 | height: 260px; 16 | overflow: hidden; 17 | border-bottom: 1px solid #dedede; 18 | position: relative; 19 | } 20 | .dt-demo-item > .dt-demo-screenshot > img { 21 | width: 100%; 22 | height: auto; 23 | } 24 | .dt-demo-item > .dt-demo-name, 25 | .dt-demo-item > .dt-demo-actions { 26 | padding: 0 10px; 27 | } 28 | .dt-demo-item > .dt-demo-actions > .button span { 29 | -webkit-background-size: 20px 20px; 30 | background-size: 20px 20px; 31 | display: inline-block; 32 | visibility: visible; 33 | float: right; 34 | vertical-align: middle; 35 | opacity: 1; 36 | filter: alpha(opacity=100); 37 | width: auto; 38 | height: auto; 39 | margin: 0; 40 | padding-left: 25px; 41 | background-position: 0px center 42 | } 43 | .dt-demo-item > .dt-demo-screenshot .dt-tag { 44 | position: absolute; 45 | top: 5px; 46 | left: 5px; 47 | background-color: rgb(255, 0, 0); 48 | padding: 5px; 49 | border-radius: 2px; 50 | line-height: 1em; 51 | color: #FFF; 52 | text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.34); 53 | } 54 | .dt-demo-item.imported > .dt-demo-screenshot .dt-tag { 55 | background-color: #00A970; 56 | } 57 | .dt-demo-item .dt-importer-response { 58 | box-sizing: border-box; 59 | position: absolute; 60 | width: 100%; 61 | height: 100%; 62 | background-color: rgba(255, 255, 255, 0.9); 63 | padding: 10px; 64 | overflow: scroll; 65 | top: -100%; 66 | opacity: 0; 67 | transition: all 0.15s ease-in-out; 68 | } 69 | .dt-demo-item .dt-importer-response.active { 70 | top: 0; 71 | opacity: 1; 72 | } 73 | .dt-demo-item .dt-importer-response .dismiss { 74 | position: absolute; 75 | top: 10px; 76 | right: 10px; 77 | background-color: rgb(255, 79, 0); 78 | color: #FFF; 79 | width: 20px; 80 | height: 20px; 81 | border-radius: 50%; 82 | text-align: center; 83 | line-height: 1.6em; 84 | cursor: pointer; 85 | } -------------------------------------------------------------------------------- /assets/img/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AminulBD/dt-demo-importer/7eeb0c02235a2ecca6c37e042018dac605bd0374/assets/img/screenshot.png -------------------------------------------------------------------------------- /assets/js/dt-importer.js: -------------------------------------------------------------------------------- 1 | jQuery('[data-dt-importer]').each(function() { 2 | var $this = jQuery(this), 3 | item = $this, 4 | tag = $this.find('.dt-tag'), 5 | content = $this.find('.dt-importer-response'); 6 | 7 | $this.find('[data-import]').click(function(e) { 8 | e.preventDefault(); 9 | var $this = jQuery(this), 10 | demo = $this.data('import'), 11 | nonce = $this.data('nonce'), 12 | data = { 13 | action: 'dt_demo_importer', 14 | nonce: nonce, 15 | id: demo 16 | }; 17 | 18 | $this.html('Please Wait...'); 19 | jQuery.post(ajaxurl, data, function(response){ 20 | content.addClass('active'); 21 | content.append(response); 22 | item.addClass('imported'); 23 | $this.html("Re-Import"); 24 | tag.html("Imported"); 25 | }); 26 | }); 27 | 28 | jQuery('.dismiss').click(function() { 29 | content.removeClass('active'); 30 | }); 31 | 32 | }); 33 | -------------------------------------------------------------------------------- /classes/abstract.class.php: -------------------------------------------------------------------------------- 1 | settings = apply_filters( 'dt_importer_settings', $settings ); 46 | $this->items = apply_filters( 'dt_importer_items', $items ); 47 | if( ! empty( $this->items ) ) { 48 | $this->addAction( 'admin_menu', 'admin_menu' ); 49 | $this->addAction( 'wp_ajax_dt_demo_importer', 'import_process' ); 50 | } 51 | } 52 | // instance 53 | public static function instance( $settings = array(), $items = array() ) { 54 | if ( is_null( self::$instance ) ) { 55 | self::$instance = new self( $settings, $items ); 56 | } 57 | return self::$instance; 58 | } 59 | 60 | // adding option page 61 | public function admin_menu() { 62 | $defaults_menu_args = array( 63 | 'menu_parent' => '', 64 | 'menu_title' => '', 65 | 'menu_type' => '', 66 | 'menu_slug' => '', 67 | 'menu_icon' => '', 68 | 'menu_capability' => 'manage_options', 69 | 'menu_position' => null, 70 | ); 71 | $args = wp_parse_args( $this->settings, $defaults_menu_args ); 72 | if( $args['menu_type'] == 'add_submenu_page' ) { 73 | call_user_func( $args['menu_type'], $args['menu_parent'], $args['menu_title'], $args['menu_title'], $args['menu_capability'], $args['menu_slug'], array( &$this, 'admin_page' ) ); 74 | } else { 75 | call_user_func( $args['menu_type'], $args['menu_title'], $args['menu_title'], $args['menu_capability'], $args['menu_slug'], array( &$this, 'admin_page' ), $args['menu_icon'], $args['menu_position'] ); 76 | } 77 | } 78 | // output demo items 79 | public function admin_page() { 80 | $nonce = wp_create_nonce('dt_importer'); 81 | ?> 82 |
83 |

84 |
85 | items as $item => $value ) : 87 | $opt = get_option($this->opt_id); 88 | 89 | $imported_class = ''; 90 | $btn_text = ''; 91 | $status = ''; 92 | if (!empty($opt[$item])) { 93 | $imported_class = 'imported'; 94 | $btn_text .= __( 'Re-Import', 'dt-importer' ); 95 | $status .= __( 'Imported', 'dt-importer' ); 96 | } else { 97 | $btn_text .= __( 'Import', 'dt-importer' ); 98 | $status .= __( 'Not Imported', 'dt-importer' ); 99 | } 100 | ?> 101 |
102 |
103 |
104 | 105 |
106 | 114 | <?php echo esc_attr($value['title']); ?> 115 |
116 |

117 |
118 | 119 | 120 |
121 | 122 |
X
123 |
124 | 125 |
126 | 129 |
130 |
131 | import_xml_data(); 142 | 143 | // Setup Option Data from Codestar 144 | $this->import_cs_options_data(); 145 | 146 | // Setup Reading 147 | $this->set_pages_for_reading(); 148 | 149 | // Setup Menu 150 | if (isset($this->items[$id]['menus'])) { 151 | $this->set_menu(); 152 | } 153 | die(); 154 | } 155 | 156 | 157 | /** 158 | * Import XML data by WordPress Importer 159 | */ 160 | public function import_xml_data() { 161 | 162 | if ( ! wp_verify_nonce( $_POST['nonce'], 'dt_importer' ) ) 163 | echo die( 'Authentication Error!!!' ); 164 | 165 | $id = $_POST['id']; 166 | $file = DT_IMPORTER_CONTENT_DIR . $id . '/content.xml'; 167 | 168 | if ( !defined('WP_LOAD_IMPORTERS') ) define('WP_LOAD_IMPORTERS', true); 169 | require_once ABSPATH . 'wp-admin/includes/import.php'; 170 | $importer_error = false; 171 | if ( !class_exists( 'WP_Importer' ) ) { 172 | $class_wp_importer = ABSPATH . 'wp-admin/includes/class-wp-importer.php'; 173 | if ( file_exists( $class_wp_importer ) ){ 174 | require_once($class_wp_importer); 175 | } else { 176 | $importer_error = true; 177 | } 178 | } 179 | if ( !class_exists( 'WP_Import' ) ) { 180 | $class_wp_import = dirname( __FILE__ ) .'/wordpress-importer.php'; 181 | if ( file_exists( $class_wp_import ) ) 182 | require_once($class_wp_import); 183 | else 184 | $importer_error = true; 185 | } 186 | if($importer_error){ 187 | die(__("Error on import", 'dt-importer')); 188 | } else { 189 | if(!is_file( $file )){ 190 | esc_html_e("File Error!!!", 'dt-importer'); 191 | } else { 192 | $wp_import = new WP_Import(); 193 | $wp_import->fetch_attachments = true; 194 | $wp_import->import( $file ); 195 | $options = get_option($this->opt_id); 196 | $options[$id] = true; 197 | update_option( $this->opt_id, $options ); 198 | } 199 | } 200 | 201 | } 202 | 203 | /** 204 | * Update Codestar Framework Options Data 205 | */ 206 | public function import_cs_options_data() { 207 | $id = $_POST['id']; 208 | $file = DT_IMPORTER_CONTENT_DIR . $id . '/options.txt'; 209 | 210 | if ( file_exists( $file ) ) { 211 | // Get file contents and decode 212 | $data = file_get_contents( $file ); 213 | $decoded_data = cs_decode_string( $data ); 214 | update_option( $this->framework_id, $decoded_data ); 215 | } 216 | } 217 | 218 | /** 219 | * Set Homepage and Front page 220 | */ 221 | public function set_pages_for_reading() { 222 | $id = $_POST['id']; 223 | 224 | // Set Home 225 | if (isset($this->items[$id]['front_page'])) { 226 | $page = get_page_by_title($this->items[$id]['front_page']); 227 | 228 | if ( isset( $page->ID ) ) { 229 | update_option( 'page_on_front', $page->ID ); 230 | update_option( 'show_on_front', 'page' ); 231 | } 232 | } 233 | 234 | // Set Blog 235 | if (isset($this->items[$id]['blog_page'])) { 236 | $page = get_page_by_title($this->items[$id]['blog_page']); 237 | 238 | if ( isset( $page->ID ) ) { 239 | update_option( 'page_for_posts', $page->ID ); 240 | update_option( 'show_on_front', 'page' ); 241 | } 242 | } 243 | } 244 | 245 | /** 246 | * Setup Menu 247 | */ 248 | public function set_menu() { 249 | $id = $_POST['id']; 250 | 251 | // Store All Menu 252 | $menu_locations = array(); 253 | 254 | foreach ($this->items[$id]['menus'] as $key => $value) { 255 | $menu = get_term_by( 'name', $value, 'nav_menu' ); 256 | if (isset($menu->term_id)) { 257 | $menu_locations[$key] = $menu->term_id; 258 | } 259 | } 260 | 261 | // Set Menu If has 262 | if (isset($menu_locations)) { 263 | set_theme_mod( 'nav_menu_locations', $menu_locations ); 264 | } 265 | } 266 | 267 | } -------------------------------------------------------------------------------- /classes/parsers.php: -------------------------------------------------------------------------------- 1 | parse( $file ); 18 | 19 | // If SimpleXML succeeds or this is an invalid WXR file then return the results 20 | if ( ! is_wp_error( $result ) || 'SimpleXML_parse_error' != $result->get_error_code() ) 21 | return $result; 22 | } else if ( extension_loaded( 'xml' ) ) { 23 | $parser = new WXR_Parser_XML; 24 | $result = $parser->parse( $file ); 25 | 26 | // If XMLParser succeeds or this is an invalid WXR file then return the results 27 | if ( ! is_wp_error( $result ) || 'XML_parse_error' != $result->get_error_code() ) 28 | return $result; 29 | } 30 | 31 | // We have a malformed XML file, so display the error and fallthrough to regex 32 | if ( isset($result) && defined('IMPORT_DEBUG') && IMPORT_DEBUG ) { 33 | echo '
';
 34 | 			if ( 'SimpleXML_parse_error' == $result->get_error_code() ) {
 35 | 				foreach  ( $result->get_error_data() as $error )
 36 | 					echo $error->line . ':' . $error->column . ' ' . esc_html( $error->message ) . "\n";
 37 | 			} else if ( 'XML_parse_error' == $result->get_error_code() ) {
 38 | 				$error = $result->get_error_data();
 39 | 				echo $error[0] . ':' . $error[1] . ' ' . esc_html( $error[2] );
 40 | 			}
 41 | 			echo '
'; 42 | echo '

' . __( 'There was an error when reading this WXR file', 'wordpress-importer' ) . '
'; 43 | echo __( 'Details are shown above. The importer will now try again with a different parser...', 'wordpress-importer' ) . '

'; 44 | } 45 | 46 | // use regular expressions if nothing else available or this is bad XML 47 | $parser = new WXR_Parser_Regex; 48 | return $parser->parse( $file ); 49 | } 50 | } 51 | 52 | /** 53 | * WXR Parser that makes use of the SimpleXML PHP extension. 54 | */ 55 | class WXR_Parser_SimpleXML { 56 | function parse( $file ) { 57 | $authors = $posts = $categories = $tags = $terms = array(); 58 | 59 | $internal_errors = libxml_use_internal_errors(true); 60 | 61 | $dom = new DOMDocument; 62 | $old_value = null; 63 | if ( function_exists( 'libxml_disable_entity_loader' ) ) { 64 | $old_value = libxml_disable_entity_loader( true ); 65 | } 66 | $success = $dom->loadXML( file_get_contents( $file ) ); 67 | if ( ! is_null( $old_value ) ) { 68 | libxml_disable_entity_loader( $old_value ); 69 | } 70 | 71 | if ( ! $success || isset( $dom->doctype ) ) { 72 | return new WP_Error( 'SimpleXML_parse_error', __( 'There was an error when reading this WXR file', 'wordpress-importer' ), libxml_get_errors() ); 73 | } 74 | 75 | $xml = simplexml_import_dom( $dom ); 76 | unset( $dom ); 77 | 78 | // halt if loading produces an error 79 | if ( ! $xml ) 80 | return new WP_Error( 'SimpleXML_parse_error', __( 'There was an error when reading this WXR file', 'wordpress-importer' ), libxml_get_errors() ); 81 | 82 | $wxr_version = $xml->xpath('/rss/channel/wp:wxr_version'); 83 | if ( ! $wxr_version ) 84 | return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer' ) ); 85 | 86 | $wxr_version = (string) trim( $wxr_version[0] ); 87 | // confirm that we are dealing with the correct file format 88 | if ( ! preg_match( '/^\d+\.\d+$/', $wxr_version ) ) 89 | return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer' ) ); 90 | 91 | $base_url = $xml->xpath('/rss/channel/wp:base_site_url'); 92 | $base_url = (string) trim( $base_url[0] ); 93 | 94 | $namespaces = $xml->getDocNamespaces(); 95 | if ( ! isset( $namespaces['wp'] ) ) 96 | $namespaces['wp'] = 'http://wordpress.org/export/1.1/'; 97 | if ( ! isset( $namespaces['excerpt'] ) ) 98 | $namespaces['excerpt'] = 'http://wordpress.org/export/1.1/excerpt/'; 99 | 100 | // grab authors 101 | foreach ( $xml->xpath('/rss/channel/wp:author') as $author_arr ) { 102 | $a = $author_arr->children( $namespaces['wp'] ); 103 | $login = (string) $a->author_login; 104 | $authors[$login] = array( 105 | 'author_id' => (int) $a->author_id, 106 | 'author_login' => $login, 107 | 'author_email' => (string) $a->author_email, 108 | 'author_display_name' => (string) $a->author_display_name, 109 | 'author_first_name' => (string) $a->author_first_name, 110 | 'author_last_name' => (string) $a->author_last_name 111 | ); 112 | } 113 | 114 | // grab cats, tags and terms 115 | foreach ( $xml->xpath('/rss/channel/wp:category') as $term_arr ) { 116 | $t = $term_arr->children( $namespaces['wp'] ); 117 | $categories[] = array( 118 | 'term_id' => (int) $t->term_id, 119 | 'category_nicename' => (string) $t->category_nicename, 120 | 'category_parent' => (string) $t->category_parent, 121 | 'cat_name' => (string) $t->cat_name, 122 | 'category_description' => (string) $t->category_description 123 | ); 124 | } 125 | 126 | foreach ( $xml->xpath('/rss/channel/wp:tag') as $term_arr ) { 127 | $t = $term_arr->children( $namespaces['wp'] ); 128 | $tags[] = array( 129 | 'term_id' => (int) $t->term_id, 130 | 'tag_slug' => (string) $t->tag_slug, 131 | 'tag_name' => (string) $t->tag_name, 132 | 'tag_description' => (string) $t->tag_description 133 | ); 134 | } 135 | 136 | foreach ( $xml->xpath('/rss/channel/wp:term') as $term_arr ) { 137 | $t = $term_arr->children( $namespaces['wp'] ); 138 | $terms[] = array( 139 | 'term_id' => (int) $t->term_id, 140 | 'term_taxonomy' => (string) $t->term_taxonomy, 141 | 'slug' => (string) $t->term_slug, 142 | 'term_parent' => (string) $t->term_parent, 143 | 'term_name' => (string) $t->term_name, 144 | 'term_description' => (string) $t->term_description 145 | ); 146 | } 147 | 148 | // grab posts 149 | foreach ( $xml->channel->item as $item ) { 150 | $post = array( 151 | 'post_title' => (string) $item->title, 152 | 'guid' => (string) $item->guid, 153 | ); 154 | 155 | $dc = $item->children( 'http://purl.org/dc/elements/1.1/' ); 156 | $post['post_author'] = (string) $dc->creator; 157 | 158 | $content = $item->children( 'http://purl.org/rss/1.0/modules/content/' ); 159 | $excerpt = $item->children( $namespaces['excerpt'] ); 160 | $post['post_content'] = (string) $content->encoded; 161 | $post['post_excerpt'] = (string) $excerpt->encoded; 162 | 163 | $wp = $item->children( $namespaces['wp'] ); 164 | $post['post_id'] = (int) $wp->post_id; 165 | $post['post_date'] = (string) $wp->post_date; 166 | $post['post_date_gmt'] = (string) $wp->post_date_gmt; 167 | $post['comment_status'] = (string) $wp->comment_status; 168 | $post['ping_status'] = (string) $wp->ping_status; 169 | $post['post_name'] = (string) $wp->post_name; 170 | $post['status'] = (string) $wp->status; 171 | $post['post_parent'] = (int) $wp->post_parent; 172 | $post['menu_order'] = (int) $wp->menu_order; 173 | $post['post_type'] = (string) $wp->post_type; 174 | $post['post_password'] = (string) $wp->post_password; 175 | $post['is_sticky'] = (int) $wp->is_sticky; 176 | 177 | if ( isset($wp->attachment_url) ) 178 | $post['attachment_url'] = (string) $wp->attachment_url; 179 | 180 | foreach ( $item->category as $c ) { 181 | $att = $c->attributes(); 182 | if ( isset( $att['nicename'] ) ) 183 | $post['terms'][] = array( 184 | 'name' => (string) $c, 185 | 'slug' => (string) $att['nicename'], 186 | 'domain' => (string) $att['domain'] 187 | ); 188 | } 189 | 190 | foreach ( $wp->postmeta as $meta ) { 191 | $post['postmeta'][] = array( 192 | 'key' => (string) $meta->meta_key, 193 | 'value' => (string) $meta->meta_value 194 | ); 195 | } 196 | 197 | foreach ( $wp->comment as $comment ) { 198 | $meta = array(); 199 | if ( isset( $comment->commentmeta ) ) { 200 | foreach ( $comment->commentmeta as $m ) { 201 | $meta[] = array( 202 | 'key' => (string) $m->meta_key, 203 | 'value' => (string) $m->meta_value 204 | ); 205 | } 206 | } 207 | 208 | $post['comments'][] = array( 209 | 'comment_id' => (int) $comment->comment_id, 210 | 'comment_author' => (string) $comment->comment_author, 211 | 'comment_author_email' => (string) $comment->comment_author_email, 212 | 'comment_author_IP' => (string) $comment->comment_author_IP, 213 | 'comment_author_url' => (string) $comment->comment_author_url, 214 | 'comment_date' => (string) $comment->comment_date, 215 | 'comment_date_gmt' => (string) $comment->comment_date_gmt, 216 | 'comment_content' => (string) $comment->comment_content, 217 | 'comment_approved' => (string) $comment->comment_approved, 218 | 'comment_type' => (string) $comment->comment_type, 219 | 'comment_parent' => (string) $comment->comment_parent, 220 | 'comment_user_id' => (int) $comment->comment_user_id, 221 | 'commentmeta' => $meta, 222 | ); 223 | } 224 | 225 | $posts[] = $post; 226 | } 227 | 228 | return array( 229 | 'authors' => $authors, 230 | 'posts' => $posts, 231 | 'categories' => $categories, 232 | 'tags' => $tags, 233 | 'terms' => $terms, 234 | 'base_url' => $base_url, 235 | 'version' => $wxr_version 236 | ); 237 | } 238 | } 239 | 240 | /** 241 | * WXR Parser that makes use of the XML Parser PHP extension. 242 | */ 243 | class WXR_Parser_XML { 244 | var $wp_tags = array( 245 | 'wp:post_id', 'wp:post_date', 'wp:post_date_gmt', 'wp:comment_status', 'wp:ping_status', 'wp:attachment_url', 246 | 'wp:status', 'wp:post_name', 'wp:post_parent', 'wp:menu_order', 'wp:post_type', 'wp:post_password', 247 | 'wp:is_sticky', 'wp:term_id', 'wp:category_nicename', 'wp:category_parent', 'wp:cat_name', 'wp:category_description', 248 | 'wp:tag_slug', 'wp:tag_name', 'wp:tag_description', 'wp:term_taxonomy', 'wp:term_parent', 249 | 'wp:term_name', 'wp:term_description', 'wp:author_id', 'wp:author_login', 'wp:author_email', 'wp:author_display_name', 250 | 'wp:author_first_name', 'wp:author_last_name', 251 | ); 252 | var $wp_sub_tags = array( 253 | 'wp:comment_id', 'wp:comment_author', 'wp:comment_author_email', 'wp:comment_author_url', 254 | 'wp:comment_author_IP', 'wp:comment_date', 'wp:comment_date_gmt', 'wp:comment_content', 255 | 'wp:comment_approved', 'wp:comment_type', 'wp:comment_parent', 'wp:comment_user_id', 256 | ); 257 | 258 | function parse( $file ) { 259 | $this->wxr_version = $this->in_post = $this->cdata = $this->data = $this->sub_data = $this->in_tag = $this->in_sub_tag = false; 260 | $this->authors = $this->posts = $this->term = $this->category = $this->tag = array(); 261 | 262 | $xml = xml_parser_create( 'UTF-8' ); 263 | xml_parser_set_option( $xml, XML_OPTION_SKIP_WHITE, 1 ); 264 | xml_parser_set_option( $xml, XML_OPTION_CASE_FOLDING, 0 ); 265 | xml_set_object( $xml, $this ); 266 | xml_set_character_data_handler( $xml, 'cdata' ); 267 | xml_set_element_handler( $xml, 'tag_open', 'tag_close' ); 268 | 269 | if ( ! xml_parse( $xml, file_get_contents( $file ), true ) ) { 270 | $current_line = xml_get_current_line_number( $xml ); 271 | $current_column = xml_get_current_column_number( $xml ); 272 | $error_code = xml_get_error_code( $xml ); 273 | $error_string = xml_error_string( $error_code ); 274 | return new WP_Error( 'XML_parse_error', 'There was an error when reading this WXR file', array( $current_line, $current_column, $error_string ) ); 275 | } 276 | xml_parser_free( $xml ); 277 | 278 | if ( ! preg_match( '/^\d+\.\d+$/', $this->wxr_version ) ) 279 | return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer' ) ); 280 | 281 | return array( 282 | 'authors' => $this->authors, 283 | 'posts' => $this->posts, 284 | 'categories' => $this->category, 285 | 'tags' => $this->tag, 286 | 'terms' => $this->term, 287 | 'base_url' => $this->base_url, 288 | 'version' => $this->wxr_version 289 | ); 290 | } 291 | 292 | function tag_open( $parse, $tag, $attr ) { 293 | if ( in_array( $tag, $this->wp_tags ) ) { 294 | $this->in_tag = substr( $tag, 3 ); 295 | return; 296 | } 297 | 298 | if ( in_array( $tag, $this->wp_sub_tags ) ) { 299 | $this->in_sub_tag = substr( $tag, 3 ); 300 | return; 301 | } 302 | 303 | switch ( $tag ) { 304 | case 'category': 305 | if ( isset($attr['domain'], $attr['nicename']) ) { 306 | $this->sub_data['domain'] = $attr['domain']; 307 | $this->sub_data['slug'] = $attr['nicename']; 308 | } 309 | break; 310 | case 'item': $this->in_post = true; 311 | case 'title': if ( $this->in_post ) $this->in_tag = 'post_title'; break; 312 | case 'guid': $this->in_tag = 'guid'; break; 313 | case 'dc:creator': $this->in_tag = 'post_author'; break; 314 | case 'content:encoded': $this->in_tag = 'post_content'; break; 315 | case 'excerpt:encoded': $this->in_tag = 'post_excerpt'; break; 316 | 317 | case 'wp:term_slug': $this->in_tag = 'slug'; break; 318 | case 'wp:meta_key': $this->in_sub_tag = 'key'; break; 319 | case 'wp:meta_value': $this->in_sub_tag = 'value'; break; 320 | } 321 | } 322 | 323 | function cdata( $parser, $cdata ) { 324 | if ( ! trim( $cdata ) ) 325 | return; 326 | 327 | $this->cdata .= trim( $cdata ); 328 | } 329 | 330 | function tag_close( $parser, $tag ) { 331 | switch ( $tag ) { 332 | case 'wp:comment': 333 | unset( $this->sub_data['key'], $this->sub_data['value'] ); // remove meta sub_data 334 | if ( ! empty( $this->sub_data ) ) 335 | $this->data['comments'][] = $this->sub_data; 336 | $this->sub_data = false; 337 | break; 338 | case 'wp:commentmeta': 339 | $this->sub_data['commentmeta'][] = array( 340 | 'key' => $this->sub_data['key'], 341 | 'value' => $this->sub_data['value'] 342 | ); 343 | break; 344 | case 'category': 345 | if ( ! empty( $this->sub_data ) ) { 346 | $this->sub_data['name'] = $this->cdata; 347 | $this->data['terms'][] = $this->sub_data; 348 | } 349 | $this->sub_data = false; 350 | break; 351 | case 'wp:postmeta': 352 | if ( ! empty( $this->sub_data ) ) 353 | $this->data['postmeta'][] = $this->sub_data; 354 | $this->sub_data = false; 355 | break; 356 | case 'item': 357 | $this->posts[] = $this->data; 358 | $this->data = false; 359 | break; 360 | case 'wp:category': 361 | case 'wp:tag': 362 | case 'wp:term': 363 | $n = substr( $tag, 3 ); 364 | array_push( $this->$n, $this->data ); 365 | $this->data = false; 366 | break; 367 | case 'wp:author': 368 | if ( ! empty($this->data['author_login']) ) 369 | $this->authors[$this->data['author_login']] = $this->data; 370 | $this->data = false; 371 | break; 372 | case 'wp:base_site_url': 373 | $this->base_url = $this->cdata; 374 | break; 375 | case 'wp:wxr_version': 376 | $this->wxr_version = $this->cdata; 377 | break; 378 | 379 | default: 380 | if ( $this->in_sub_tag ) { 381 | $this->sub_data[$this->in_sub_tag] = ! empty( $this->cdata ) ? $this->cdata : ''; 382 | $this->in_sub_tag = false; 383 | } else if ( $this->in_tag ) { 384 | $this->data[$this->in_tag] = ! empty( $this->cdata ) ? $this->cdata : ''; 385 | $this->in_tag = false; 386 | } 387 | } 388 | 389 | $this->cdata = false; 390 | } 391 | } 392 | 393 | /** 394 | * WXR Parser that uses regular expressions. Fallback for installs without an XML parser. 395 | */ 396 | class WXR_Parser_Regex { 397 | var $authors = array(); 398 | var $posts = array(); 399 | var $categories = array(); 400 | var $tags = array(); 401 | var $terms = array(); 402 | var $base_url = ''; 403 | 404 | function WXR_Parser_Regex() { 405 | $this->__construct(); 406 | } 407 | 408 | function __construct() { 409 | $this->has_gzip = is_callable( 'gzopen' ); 410 | } 411 | 412 | function parse( $file ) { 413 | $wxr_version = $in_post = false; 414 | 415 | $fp = $this->fopen( $file, 'r' ); 416 | if ( $fp ) { 417 | while ( ! $this->feof( $fp ) ) { 418 | $importline = rtrim( $this->fgets( $fp ) ); 419 | 420 | if ( ! $wxr_version && preg_match( '|(\d+\.\d+)|', $importline, $version ) ) 421 | $wxr_version = $version[1]; 422 | 423 | if ( false !== strpos( $importline, '' ) ) { 424 | preg_match( '|(.*?)|is', $importline, $url ); 425 | $this->base_url = $url[1]; 426 | continue; 427 | } 428 | if ( false !== strpos( $importline, '' ) ) { 429 | preg_match( '|(.*?)|is', $importline, $category ); 430 | $this->categories[] = $this->process_category( $category[1] ); 431 | continue; 432 | } 433 | if ( false !== strpos( $importline, '' ) ) { 434 | preg_match( '|(.*?)|is', $importline, $tag ); 435 | $this->tags[] = $this->process_tag( $tag[1] ); 436 | continue; 437 | } 438 | if ( false !== strpos( $importline, '' ) ) { 439 | preg_match( '|(.*?)|is', $importline, $term ); 440 | $this->terms[] = $this->process_term( $term[1] ); 441 | continue; 442 | } 443 | if ( false !== strpos( $importline, '' ) ) { 444 | preg_match( '|(.*?)|is', $importline, $author ); 445 | $a = $this->process_author( $author[1] ); 446 | $this->authors[$a['author_login']] = $a; 447 | continue; 448 | } 449 | if ( false !== strpos( $importline, '' ) ) { 450 | $post = ''; 451 | $in_post = true; 452 | continue; 453 | } 454 | if ( false !== strpos( $importline, '' ) ) { 455 | $in_post = false; 456 | $this->posts[] = $this->process_post( $post ); 457 | continue; 458 | } 459 | if ( $in_post ) { 460 | $post .= $importline . "\n"; 461 | } 462 | } 463 | 464 | $this->fclose($fp); 465 | } 466 | 467 | if ( ! $wxr_version ) 468 | return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer' ) ); 469 | 470 | return array( 471 | 'authors' => $this->authors, 472 | 'posts' => $this->posts, 473 | 'categories' => $this->categories, 474 | 'tags' => $this->tags, 475 | 'terms' => $this->terms, 476 | 'base_url' => $this->base_url, 477 | 'version' => $wxr_version 478 | ); 479 | } 480 | 481 | function get_tag( $string, $tag ) { 482 | preg_match( "|<$tag.*?>(.*?)|is", $string, $return ); 483 | if ( isset( $return[1] ) ) { 484 | if ( substr( $return[1], 0, 9 ) == '' ) !== false ) { 486 | preg_match_all( '||s', $return[1], $matches ); 487 | $return = ''; 488 | foreach( $matches[1] as $match ) 489 | $return .= $match; 490 | } else { 491 | $return = preg_replace( '|^$|s', '$1', $return[1] ); 492 | } 493 | } else { 494 | $return = $return[1]; 495 | } 496 | } else { 497 | $return = ''; 498 | } 499 | return $return; 500 | } 501 | 502 | function process_category( $c ) { 503 | return array( 504 | 'term_id' => $this->get_tag( $c, 'wp:term_id' ), 505 | 'cat_name' => $this->get_tag( $c, 'wp:cat_name' ), 506 | 'category_nicename' => $this->get_tag( $c, 'wp:category_nicename' ), 507 | 'category_parent' => $this->get_tag( $c, 'wp:category_parent' ), 508 | 'category_description' => $this->get_tag( $c, 'wp:category_description' ), 509 | ); 510 | } 511 | 512 | function process_tag( $t ) { 513 | return array( 514 | 'term_id' => $this->get_tag( $t, 'wp:term_id' ), 515 | 'tag_name' => $this->get_tag( $t, 'wp:tag_name' ), 516 | 'tag_slug' => $this->get_tag( $t, 'wp:tag_slug' ), 517 | 'tag_description' => $this->get_tag( $t, 'wp:tag_description' ), 518 | ); 519 | } 520 | 521 | function process_term( $t ) { 522 | return array( 523 | 'term_id' => $this->get_tag( $t, 'wp:term_id' ), 524 | 'term_taxonomy' => $this->get_tag( $t, 'wp:term_taxonomy' ), 525 | 'slug' => $this->get_tag( $t, 'wp:term_slug' ), 526 | 'term_parent' => $this->get_tag( $t, 'wp:term_parent' ), 527 | 'term_name' => $this->get_tag( $t, 'wp:term_name' ), 528 | 'term_description' => $this->get_tag( $t, 'wp:term_description' ), 529 | ); 530 | } 531 | 532 | function process_author( $a ) { 533 | return array( 534 | 'author_id' => $this->get_tag( $a, 'wp:author_id' ), 535 | 'author_login' => $this->get_tag( $a, 'wp:author_login' ), 536 | 'author_email' => $this->get_tag( $a, 'wp:author_email' ), 537 | 'author_display_name' => $this->get_tag( $a, 'wp:author_display_name' ), 538 | 'author_first_name' => $this->get_tag( $a, 'wp:author_first_name' ), 539 | 'author_last_name' => $this->get_tag( $a, 'wp:author_last_name' ), 540 | ); 541 | } 542 | 543 | function process_post( $post ) { 544 | $post_id = $this->get_tag( $post, 'wp:post_id' ); 545 | $post_title = $this->get_tag( $post, 'title' ); 546 | $post_date = $this->get_tag( $post, 'wp:post_date' ); 547 | $post_date_gmt = $this->get_tag( $post, 'wp:post_date_gmt' ); 548 | $comment_status = $this->get_tag( $post, 'wp:comment_status' ); 549 | $ping_status = $this->get_tag( $post, 'wp:ping_status' ); 550 | $status = $this->get_tag( $post, 'wp:status' ); 551 | $post_name = $this->get_tag( $post, 'wp:post_name' ); 552 | $post_parent = $this->get_tag( $post, 'wp:post_parent' ); 553 | $menu_order = $this->get_tag( $post, 'wp:menu_order' ); 554 | $post_type = $this->get_tag( $post, 'wp:post_type' ); 555 | $post_password = $this->get_tag( $post, 'wp:post_password' ); 556 | $is_sticky = $this->get_tag( $post, 'wp:is_sticky' ); 557 | $guid = $this->get_tag( $post, 'guid' ); 558 | $post_author = $this->get_tag( $post, 'dc:creator' ); 559 | 560 | $post_excerpt = $this->get_tag( $post, 'excerpt:encoded' ); 561 | $post_excerpt = preg_replace_callback( '|<(/?[A-Z]+)|', array( &$this, '_normalize_tag' ), $post_excerpt ); 562 | $post_excerpt = str_replace( '
', '
', $post_excerpt ); 563 | $post_excerpt = str_replace( '
', '
', $post_excerpt ); 564 | 565 | $post_content = $this->get_tag( $post, 'content:encoded' ); 566 | $post_content = preg_replace_callback( '|<(/?[A-Z]+)|', array( &$this, '_normalize_tag' ), $post_content ); 567 | $post_content = str_replace( '
', '
', $post_content ); 568 | $post_content = str_replace( '
', '
', $post_content ); 569 | 570 | $postdata = compact( 'post_id', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_excerpt', 571 | 'post_title', 'status', 'post_name', 'comment_status', 'ping_status', 'guid', 'post_parent', 572 | 'menu_order', 'post_type', 'post_password', 'is_sticky' 573 | ); 574 | 575 | $attachment_url = $this->get_tag( $post, 'wp:attachment_url' ); 576 | if ( $attachment_url ) 577 | $postdata['attachment_url'] = $attachment_url; 578 | 579 | preg_match_all( '|(.+?)|is', $post, $terms, PREG_SET_ORDER ); 580 | foreach ( $terms as $t ) { 581 | $post_terms[] = array( 582 | 'slug' => $t[2], 583 | 'domain' => $t[1], 584 | 'name' => str_replace( array( '' ), '', $t[3] ), 585 | ); 586 | } 587 | if ( ! empty( $post_terms ) ) $postdata['terms'] = $post_terms; 588 | 589 | preg_match_all( '|(.+?)|is', $post, $comments ); 590 | $comments = $comments[1]; 591 | if ( $comments ) { 592 | foreach ( $comments as $comment ) { 593 | preg_match_all( '|(.+?)|is', $comment, $commentmeta ); 594 | $commentmeta = $commentmeta[1]; 595 | $c_meta = array(); 596 | foreach ( $commentmeta as $m ) { 597 | $c_meta[] = array( 598 | 'key' => $this->get_tag( $m, 'wp:meta_key' ), 599 | 'value' => $this->get_tag( $m, 'wp:meta_value' ), 600 | ); 601 | } 602 | 603 | $post_comments[] = array( 604 | 'comment_id' => $this->get_tag( $comment, 'wp:comment_id' ), 605 | 'comment_author' => $this->get_tag( $comment, 'wp:comment_author' ), 606 | 'comment_author_email' => $this->get_tag( $comment, 'wp:comment_author_email' ), 607 | 'comment_author_IP' => $this->get_tag( $comment, 'wp:comment_author_IP' ), 608 | 'comment_author_url' => $this->get_tag( $comment, 'wp:comment_author_url' ), 609 | 'comment_date' => $this->get_tag( $comment, 'wp:comment_date' ), 610 | 'comment_date_gmt' => $this->get_tag( $comment, 'wp:comment_date_gmt' ), 611 | 'comment_content' => $this->get_tag( $comment, 'wp:comment_content' ), 612 | 'comment_approved' => $this->get_tag( $comment, 'wp:comment_approved' ), 613 | 'comment_type' => $this->get_tag( $comment, 'wp:comment_type' ), 614 | 'comment_parent' => $this->get_tag( $comment, 'wp:comment_parent' ), 615 | 'comment_user_id' => $this->get_tag( $comment, 'wp:comment_user_id' ), 616 | 'commentmeta' => $c_meta, 617 | ); 618 | } 619 | } 620 | if ( ! empty( $post_comments ) ) $postdata['comments'] = $post_comments; 621 | 622 | preg_match_all( '|(.+?)|is', $post, $postmeta ); 623 | $postmeta = $postmeta[1]; 624 | if ( $postmeta ) { 625 | foreach ( $postmeta as $p ) { 626 | $post_postmeta[] = array( 627 | 'key' => $this->get_tag( $p, 'wp:meta_key' ), 628 | 'value' => $this->get_tag( $p, 'wp:meta_value' ), 629 | ); 630 | } 631 | } 632 | if ( ! empty( $post_postmeta ) ) $postdata['postmeta'] = $post_postmeta; 633 | 634 | return $postdata; 635 | } 636 | 637 | function _normalize_tag( $matches ) { 638 | return '<' . strtolower( $matches[1] ); 639 | } 640 | 641 | function fopen( $filename, $mode = 'r' ) { 642 | if ( $this->has_gzip ) 643 | return gzopen( $filename, $mode ); 644 | return fopen( $filename, $mode ); 645 | } 646 | 647 | function feof( $fp ) { 648 | if ( $this->has_gzip ) 649 | return gzeof( $fp ); 650 | return feof( $fp ); 651 | } 652 | 653 | function fgets( $fp, $len = 8192 ) { 654 | if ( $this->has_gzip ) 655 | return gzgets( $fp, $len ); 656 | return fgets( $fp, $len ); 657 | } 658 | 659 | function fclose( $fp ) { 660 | if ( $this->has_gzip ) 661 | return gzclose( $fp ); 662 | return fclose( $fp ); 663 | } 664 | } 665 | -------------------------------------------------------------------------------- /classes/wordpress-importer.php: -------------------------------------------------------------------------------- 1 | header(); 75 | 76 | $step = empty( $_GET['step'] ) ? 0 : (int) $_GET['step']; 77 | switch ( $step ) { 78 | case 0: 79 | $this->greet(); 80 | break; 81 | case 1: 82 | check_admin_referer( 'import-upload' ); 83 | if ( $this->handle_upload() ) 84 | $this->import_options(); 85 | break; 86 | case 2: 87 | check_admin_referer( 'import-wordpress' ); 88 | $this->fetch_attachments = ( ! empty( $_POST['fetch_attachments'] ) && $this->allow_fetch_attachments() ); 89 | $this->id = (int) $_POST['import_id']; 90 | $file = get_attached_file( $this->id ); 91 | set_time_limit(0); 92 | $this->import( $file ); 93 | break; 94 | } 95 | 96 | $this->footer(); 97 | } 98 | 99 | /** 100 | * The main controller for the actual import stage. 101 | * 102 | * @param string $file Path to the WXR file for importing 103 | */ 104 | function import( $file ) { 105 | add_filter( 'import_post_meta_key', array( $this, 'is_valid_meta_key' ) ); 106 | add_filter( 'http_request_timeout', array( &$this, 'bump_request_timeout' ) ); 107 | 108 | $this->import_start( $file ); 109 | 110 | $this->get_author_mapping(); 111 | 112 | wp_suspend_cache_invalidation( true ); 113 | $this->process_categories(); 114 | $this->process_tags(); 115 | $this->process_terms(); 116 | $this->process_posts(); 117 | wp_suspend_cache_invalidation( false ); 118 | 119 | // update incorrect/missing information in the DB 120 | $this->backfill_parents(); 121 | $this->backfill_attachment_urls(); 122 | $this->remap_featured_images(); 123 | 124 | $this->import_end(); 125 | } 126 | 127 | /** 128 | * Parses the WXR file and prepares us for the task of processing parsed data 129 | * 130 | * @param string $file Path to the WXR file for importing 131 | */ 132 | function import_start( $file ) { 133 | if ( ! is_file($file) ) { 134 | echo '

' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '
'; 135 | echo __( 'The file does not exist, please try again.', 'wordpress-importer' ) . '

'; 136 | $this->footer(); 137 | die(); 138 | } 139 | 140 | $import_data = $this->parse( $file ); 141 | 142 | if ( is_wp_error( $import_data ) ) { 143 | echo '

' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '
'; 144 | echo esc_html( $import_data->get_error_message() ) . '

'; 145 | $this->footer(); 146 | die(); 147 | } 148 | 149 | $this->version = $import_data['version']; 150 | $this->get_authors_from_import( $import_data ); 151 | $this->posts = $import_data['posts']; 152 | $this->terms = $import_data['terms']; 153 | $this->categories = $import_data['categories']; 154 | $this->tags = $import_data['tags']; 155 | $this->base_url = esc_url( $import_data['base_url'] ); 156 | 157 | wp_defer_term_counting( true ); 158 | wp_defer_comment_counting( true ); 159 | 160 | do_action( 'import_start' ); 161 | } 162 | 163 | /** 164 | * Performs post-import cleanup of files and the cache 165 | */ 166 | function import_end() { 167 | wp_import_cleanup( $this->id ); 168 | 169 | wp_cache_flush(); 170 | foreach ( get_taxonomies() as $tax ) { 171 | delete_option( "{$tax}_children" ); 172 | _get_term_hierarchy( $tax ); 173 | } 174 | 175 | wp_defer_term_counting( false ); 176 | wp_defer_comment_counting( false ); 177 | 178 | echo '

' . __( 'All done.', 'wordpress-importer' ) . ' ' . __( 'Have fun!', 'wordpress-importer' ) . '' . '

'; 179 | echo '

' . __( 'Remember to update the passwords and roles of imported users.', 'wordpress-importer' ) . '

'; 180 | 181 | do_action( 'import_end' ); 182 | } 183 | 184 | /** 185 | * Handles the WXR upload and initial parsing of the file to prepare for 186 | * displaying author import options 187 | * 188 | * @return bool False if error uploading or invalid file, true otherwise 189 | */ 190 | function handle_upload() { 191 | $file = wp_import_handle_upload(); 192 | 193 | if ( isset( $file['error'] ) ) { 194 | echo '

' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '
'; 195 | echo esc_html( $file['error'] ) . '

'; 196 | return false; 197 | } else if ( ! file_exists( $file['file'] ) ) { 198 | echo '

' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '
'; 199 | printf( __( 'The export file could not be found at %s. It is likely that this was caused by a permissions problem.', 'wordpress-importer' ), esc_html( $file['file'] ) ); 200 | echo '

'; 201 | return false; 202 | } 203 | 204 | $this->id = (int) $file['id']; 205 | $import_data = $this->parse( $file['file'] ); 206 | if ( is_wp_error( $import_data ) ) { 207 | echo '

' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '
'; 208 | echo esc_html( $import_data->get_error_message() ) . '

'; 209 | return false; 210 | } 211 | 212 | $this->version = $import_data['version']; 213 | if ( $this->version > $this->max_wxr_version ) { 214 | echo '

'; 215 | printf( __( 'This WXR file (version %s) may not be supported by this version of the importer. Please consider updating.', 'wordpress-importer' ), esc_html($import_data['version']) ); 216 | echo '

'; 217 | } 218 | 219 | $this->get_authors_from_import( $import_data ); 220 | 221 | return true; 222 | } 223 | 224 | /** 225 | * Retrieve authors from parsed WXR data 226 | * 227 | * Uses the provided author information from WXR 1.1 files 228 | * or extracts info from each post for WXR 1.0 files 229 | * 230 | * @param array $import_data Data returned by a WXR parser 231 | */ 232 | function get_authors_from_import( $import_data ) { 233 | if ( ! empty( $import_data['authors'] ) ) { 234 | $this->authors = $import_data['authors']; 235 | // no author information, grab it from the posts 236 | } else { 237 | foreach ( $import_data['posts'] as $post ) { 238 | $login = sanitize_user( $post['post_author'], true ); 239 | if ( empty( $login ) ) { 240 | printf( __( 'Failed to import author %s. Their posts will be attributed to the current user.', 'wordpress-importer' ), esc_html( $post['post_author'] ) ); 241 | echo '
'; 242 | continue; 243 | } 244 | 245 | if ( ! isset($this->authors[$login]) ) 246 | $this->authors[$login] = array( 247 | 'author_login' => $login, 248 | 'author_display_name' => $post['post_author'] 249 | ); 250 | } 251 | } 252 | } 253 | 254 | /** 255 | * Display pre-import options, author importing/mapping and option to 256 | * fetch attachments 257 | */ 258 | function import_options() { 259 | $j = 0; 260 | ?> 261 |
262 | 263 | 264 | 265 | authors ) ) : ?> 266 |

267 |

admins entries.', 'wordpress-importer' ); ?>

268 | allow_create_users() ) : ?> 269 |

270 | 271 |
    272 | authors as $author ) : ?> 273 |
  1. author_select( $j++, $author ); ?>
  2. 274 | 275 |
276 | 277 | 278 | allow_fetch_attachments() ) : ?> 279 |

280 |

281 | 282 | 283 |

284 | 285 | 286 |

287 |
288 | ' . esc_html( $author['author_display_name'] ); 301 | if ( $this->version != '1.0' ) echo ' (' . esc_html( $author['author_login'] ) . ')'; 302 | echo '
'; 303 | 304 | if ( $this->version != '1.0' ) 305 | echo '
'; 306 | 307 | $create_users = $this->allow_create_users(); 308 | if ( $create_users ) { 309 | if ( $this->version != '1.0' ) { 310 | _e( 'or create new user with login name:', 'wordpress-importer' ); 311 | $value = ''; 312 | } else { 313 | _e( 'as a new user:', 'wordpress-importer' ); 314 | $value = esc_attr( sanitize_user( $author['author_login'], true ) ); 315 | } 316 | 317 | echo '
'; 318 | } 319 | 320 | if ( ! $create_users && $this->version == '1.0' ) 321 | _e( 'assign posts to an existing user:', 'wordpress-importer' ); 322 | else 323 | _e( 'or assign posts to an existing user:', 'wordpress-importer' ); 324 | wp_dropdown_users( array( 'name' => "user_map[$n]", 'multi' => true, 'show_option_all' => __( '- Select -', 'wordpress-importer' ) ) ); 325 | echo ''; 326 | 327 | if ( $this->version != '1.0' ) 328 | echo '
'; 329 | } 330 | 331 | /** 332 | * Map old author logins to local user IDs based on decisions made 333 | * in import options form. Can map to an existing user, create a new user 334 | * or falls back to the current user in case of error with either of the previous 335 | */ 336 | function get_author_mapping() { 337 | if ( ! isset( $_POST['imported_authors'] ) ) 338 | return; 339 | 340 | $create_users = $this->allow_create_users(); 341 | 342 | foreach ( (array) $_POST['imported_authors'] as $i => $old_login ) { 343 | // Multisite adds strtolower to sanitize_user. Need to sanitize here to stop breakage in process_posts. 344 | $santized_old_login = sanitize_user( $old_login, true ); 345 | $old_id = isset( $this->authors[$old_login]['author_id'] ) ? intval($this->authors[$old_login]['author_id']) : false; 346 | 347 | if ( ! empty( $_POST['user_map'][$i] ) ) { 348 | $user = get_userdata( intval($_POST['user_map'][$i]) ); 349 | if ( isset( $user->ID ) ) { 350 | if ( $old_id ) 351 | $this->processed_authors[$old_id] = $user->ID; 352 | $this->author_mapping[$santized_old_login] = $user->ID; 353 | } 354 | } else if ( $create_users ) { 355 | if ( ! empty($_POST['user_new'][$i]) ) { 356 | $user_id = wp_create_user( $_POST['user_new'][$i], wp_generate_password() ); 357 | } else if ( $this->version != '1.0' ) { 358 | $user_data = array( 359 | 'user_login' => $old_login, 360 | 'user_pass' => wp_generate_password(), 361 | 'user_email' => isset( $this->authors[$old_login]['author_email'] ) ? $this->authors[$old_login]['author_email'] : '', 362 | 'display_name' => $this->authors[$old_login]['author_display_name'], 363 | 'first_name' => isset( $this->authors[$old_login]['author_first_name'] ) ? $this->authors[$old_login]['author_first_name'] : '', 364 | 'last_name' => isset( $this->authors[$old_login]['author_last_name'] ) ? $this->authors[$old_login]['author_last_name'] : '', 365 | ); 366 | $user_id = wp_insert_user( $user_data ); 367 | } 368 | 369 | if ( ! is_wp_error( $user_id ) ) { 370 | if ( $old_id ) 371 | $this->processed_authors[$old_id] = $user_id; 372 | $this->author_mapping[$santized_old_login] = $user_id; 373 | } else { 374 | printf( __( 'Failed to create new user for %s. Their posts will be attributed to the current user.', 'wordpress-importer' ), esc_html($this->authors[$old_login]['author_display_name']) ); 375 | if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG ) 376 | echo ' ' . $user_id->get_error_message(); 377 | echo '
'; 378 | } 379 | } 380 | 381 | // failsafe: if the user_id was invalid, default to the current user 382 | if ( ! isset( $this->author_mapping[$santized_old_login] ) ) { 383 | if ( $old_id ) 384 | $this->processed_authors[$old_id] = (int) get_current_user_id(); 385 | $this->author_mapping[$santized_old_login] = (int) get_current_user_id(); 386 | } 387 | } 388 | } 389 | 390 | /** 391 | * Create new categories based on import information 392 | * 393 | * Doesn't create a new category if its slug already exists 394 | */ 395 | function process_categories() { 396 | $this->categories = apply_filters( 'wp_import_categories', $this->categories ); 397 | 398 | if ( empty( $this->categories ) ) 399 | return; 400 | 401 | foreach ( $this->categories as $cat ) { 402 | // if the category already exists leave it alone 403 | $term_id = term_exists( $cat['category_nicename'], 'category' ); 404 | if ( $term_id ) { 405 | if ( is_array($term_id) ) $term_id = $term_id['term_id']; 406 | if ( isset($cat['term_id']) ) 407 | $this->processed_terms[intval($cat['term_id'])] = (int) $term_id; 408 | continue; 409 | } 410 | 411 | $category_parent = empty( $cat['category_parent'] ) ? 0 : category_exists( $cat['category_parent'] ); 412 | $category_description = isset( $cat['category_description'] ) ? $cat['category_description'] : ''; 413 | $catarr = array( 414 | 'category_nicename' => $cat['category_nicename'], 415 | 'category_parent' => $category_parent, 416 | 'cat_name' => $cat['cat_name'], 417 | 'category_description' => $category_description 418 | ); 419 | 420 | $id = wp_insert_category( $catarr ); 421 | if ( ! is_wp_error( $id ) ) { 422 | if ( isset($cat['term_id']) ) 423 | $this->processed_terms[intval($cat['term_id'])] = $id; 424 | } else { 425 | printf( __( 'Failed to import category %s', 'wordpress-importer' ), esc_html($cat['category_nicename']) ); 426 | if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG ) 427 | echo ': ' . $id->get_error_message(); 428 | echo '
'; 429 | continue; 430 | } 431 | } 432 | 433 | unset( $this->categories ); 434 | } 435 | 436 | /** 437 | * Create new post tags based on import information 438 | * 439 | * Doesn't create a tag if its slug already exists 440 | */ 441 | function process_tags() { 442 | $this->tags = apply_filters( 'wp_import_tags', $this->tags ); 443 | 444 | if ( empty( $this->tags ) ) 445 | return; 446 | 447 | foreach ( $this->tags as $tag ) { 448 | // if the tag already exists leave it alone 449 | $term_id = term_exists( $tag['tag_slug'], 'post_tag' ); 450 | if ( $term_id ) { 451 | if ( is_array($term_id) ) $term_id = $term_id['term_id']; 452 | if ( isset($tag['term_id']) ) 453 | $this->processed_terms[intval($tag['term_id'])] = (int) $term_id; 454 | continue; 455 | } 456 | 457 | $tag_desc = isset( $tag['tag_description'] ) ? $tag['tag_description'] : ''; 458 | $tagarr = array( 'slug' => $tag['tag_slug'], 'description' => $tag_desc ); 459 | 460 | $id = wp_insert_term( $tag['tag_name'], 'post_tag', $tagarr ); 461 | if ( ! is_wp_error( $id ) ) { 462 | if ( isset($tag['term_id']) ) 463 | $this->processed_terms[intval($tag['term_id'])] = $id['term_id']; 464 | } else { 465 | printf( __( 'Failed to import post tag %s', 'wordpress-importer' ), esc_html($tag['tag_name']) ); 466 | if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG ) 467 | echo ': ' . $id->get_error_message(); 468 | echo '
'; 469 | continue; 470 | } 471 | } 472 | 473 | unset( $this->tags ); 474 | } 475 | 476 | /** 477 | * Create new terms based on import information 478 | * 479 | * Doesn't create a term its slug already exists 480 | */ 481 | function process_terms() { 482 | $this->terms = apply_filters( 'wp_import_terms', $this->terms ); 483 | 484 | if ( empty( $this->terms ) ) 485 | return; 486 | 487 | foreach ( $this->terms as $term ) { 488 | // if the term already exists in the correct taxonomy leave it alone 489 | $term_id = term_exists( $term['slug'], $term['term_taxonomy'] ); 490 | if ( $term_id ) { 491 | if ( is_array($term_id) ) $term_id = $term_id['term_id']; 492 | if ( isset($term['term_id']) ) 493 | $this->processed_terms[intval($term['term_id'])] = (int) $term_id; 494 | continue; 495 | } 496 | 497 | if ( empty( $term['term_parent'] ) ) { 498 | $parent = 0; 499 | } else { 500 | $parent = term_exists( $term['term_parent'], $term['term_taxonomy'] ); 501 | if ( is_array( $parent ) ) $parent = $parent['term_id']; 502 | } 503 | $description = isset( $term['term_description'] ) ? $term['term_description'] : ''; 504 | $termarr = array( 'slug' => $term['slug'], 'description' => $description, 'parent' => intval($parent) ); 505 | 506 | $id = wp_insert_term( $term['term_name'], $term['term_taxonomy'], $termarr ); 507 | if ( ! is_wp_error( $id ) ) { 508 | if ( isset($term['term_id']) ) 509 | $this->processed_terms[intval($term['term_id'])] = $id['term_id']; 510 | } else { 511 | printf( __( 'Failed to import %s %s', 'wordpress-importer' ), esc_html($term['term_taxonomy']), esc_html($term['term_name']) ); 512 | if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG ) 513 | echo ': ' . $id->get_error_message(); 514 | echo '
'; 515 | continue; 516 | } 517 | } 518 | 519 | unset( $this->terms ); 520 | } 521 | 522 | /** 523 | * Create new posts based on import information 524 | * 525 | * Posts marked as having a parent which doesn't exist will become top level items. 526 | * Doesn't create a new post if: the post type doesn't exist, the given post ID 527 | * is already noted as imported or a post with the same title and date already exists. 528 | * Note that new/updated terms, comments and meta are imported for the last of the above. 529 | */ 530 | function process_posts() { 531 | $this->posts = apply_filters( 'wp_import_posts', $this->posts ); 532 | 533 | foreach ( $this->posts as $post ) { 534 | $post = apply_filters( 'wp_import_post_data_raw', $post ); 535 | 536 | if ( ! post_type_exists( $post['post_type'] ) ) { 537 | printf( __( 'Failed to import “%s”: Invalid post type %s', 'wordpress-importer' ), 538 | esc_html($post['post_title']), esc_html($post['post_type']) ); 539 | echo '
'; 540 | do_action( 'wp_import_post_exists', $post ); 541 | continue; 542 | } 543 | 544 | if ( isset( $this->processed_posts[$post['post_id']] ) && ! empty( $post['post_id'] ) ) 545 | continue; 546 | 547 | if ( $post['status'] == 'auto-draft' ) 548 | continue; 549 | 550 | if ( 'nav_menu_item' == $post['post_type'] ) { 551 | $this->process_menu_item( $post ); 552 | continue; 553 | } 554 | 555 | $post_type_object = get_post_type_object( $post['post_type'] ); 556 | 557 | $post_exists = post_exists( $post['post_title'], '', $post['post_date'] ); 558 | if ( $post_exists && get_post_type( $post_exists ) == $post['post_type'] ) { 559 | printf( __('%s “%s” already exists.', 'wordpress-importer'), $post_type_object->labels->singular_name, esc_html($post['post_title']) ); 560 | echo '
'; 561 | $comment_post_ID = $post_id = $post_exists; 562 | } else { 563 | $post_parent = (int) $post['post_parent']; 564 | if ( $post_parent ) { 565 | // if we already know the parent, map it to the new local ID 566 | if ( isset( $this->processed_posts[$post_parent] ) ) { 567 | $post_parent = $this->processed_posts[$post_parent]; 568 | // otherwise record the parent for later 569 | } else { 570 | $this->post_orphans[intval($post['post_id'])] = $post_parent; 571 | $post_parent = 0; 572 | } 573 | } 574 | 575 | // map the post author 576 | $author = sanitize_user( $post['post_author'], true ); 577 | if ( isset( $this->author_mapping[$author] ) ) 578 | $author = $this->author_mapping[$author]; 579 | else 580 | $author = (int) get_current_user_id(); 581 | 582 | $postdata = array( 583 | 'import_id' => $post['post_id'], 'post_author' => $author, 'post_date' => $post['post_date'], 584 | 'post_date_gmt' => $post['post_date_gmt'], 'post_content' => $post['post_content'], 585 | 'post_excerpt' => $post['post_excerpt'], 'post_title' => $post['post_title'], 586 | 'post_status' => $post['status'], 'post_name' => $post['post_name'], 587 | 'comment_status' => $post['comment_status'], 'ping_status' => $post['ping_status'], 588 | 'guid' => $post['guid'], 'post_parent' => $post_parent, 'menu_order' => $post['menu_order'], 589 | 'post_type' => $post['post_type'], 'post_password' => $post['post_password'] 590 | ); 591 | 592 | $original_post_ID = $post['post_id']; 593 | $postdata = apply_filters( 'wp_import_post_data_processed', $postdata, $post ); 594 | 595 | if ( 'attachment' == $postdata['post_type'] ) { 596 | $remote_url = ! empty($post['attachment_url']) ? $post['attachment_url'] : $post['guid']; 597 | 598 | // try to use _wp_attached file for upload folder placement to ensure the same location as the export site 599 | // e.g. location is 2003/05/image.jpg but the attachment post_date is 2010/09, see media_handle_upload() 600 | $postdata['upload_date'] = $post['post_date']; 601 | if ( isset( $post['postmeta'] ) ) { 602 | foreach( $post['postmeta'] as $meta ) { 603 | if ( $meta['key'] == '_wp_attached_file' ) { 604 | if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta['value'], $matches ) ) 605 | $postdata['upload_date'] = $matches[0]; 606 | break; 607 | } 608 | } 609 | } 610 | 611 | $comment_post_ID = $post_id = $this->process_attachment( $postdata, $remote_url ); 612 | } else { 613 | $comment_post_ID = $post_id = wp_insert_post( $postdata, true ); 614 | do_action( 'wp_import_insert_post', $post_id, $original_post_ID, $postdata, $post ); 615 | } 616 | 617 | if ( is_wp_error( $post_id ) ) { 618 | printf( __( 'Failed to import %s “%s”', 'wordpress-importer' ), 619 | $post_type_object->labels->singular_name, esc_html($post['post_title']) ); 620 | if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG ) 621 | echo ': ' . $post_id->get_error_message(); 622 | echo '
'; 623 | continue; 624 | } 625 | 626 | if ( $post['is_sticky'] == 1 ) 627 | stick_post( $post_id ); 628 | } 629 | 630 | // map pre-import ID to local ID 631 | $this->processed_posts[intval($post['post_id'])] = (int) $post_id; 632 | 633 | if ( ! isset( $post['terms'] ) ) 634 | $post['terms'] = array(); 635 | 636 | $post['terms'] = apply_filters( 'wp_import_post_terms', $post['terms'], $post_id, $post ); 637 | 638 | // add categories, tags and other terms 639 | if ( ! empty( $post['terms'] ) ) { 640 | $terms_to_set = array(); 641 | foreach ( $post['terms'] as $term ) { 642 | // back compat with WXR 1.0 map 'tag' to 'post_tag' 643 | $taxonomy = ( 'tag' == $term['domain'] ) ? 'post_tag' : $term['domain']; 644 | $term_exists = term_exists( $term['slug'], $taxonomy ); 645 | $term_id = is_array( $term_exists ) ? $term_exists['term_id'] : $term_exists; 646 | if ( ! $term_id ) { 647 | $t = wp_insert_term( $term['name'], $taxonomy, array( 'slug' => $term['slug'] ) ); 648 | if ( ! is_wp_error( $t ) ) { 649 | $term_id = $t['term_id']; 650 | do_action( 'wp_import_insert_term', $t, $term, $post_id, $post ); 651 | } else { 652 | printf( __( 'Failed to import %s %s', 'wordpress-importer' ), esc_html($taxonomy), esc_html($term['name']) ); 653 | if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG ) 654 | echo ': ' . $t->get_error_message(); 655 | echo '
'; 656 | do_action( 'wp_import_insert_term_failed', $t, $term, $post_id, $post ); 657 | continue; 658 | } 659 | } 660 | $terms_to_set[$taxonomy][] = intval( $term_id ); 661 | } 662 | 663 | foreach ( $terms_to_set as $tax => $ids ) { 664 | $tt_ids = wp_set_post_terms( $post_id, $ids, $tax ); 665 | do_action( 'wp_import_set_post_terms', $tt_ids, $ids, $tax, $post_id, $post ); 666 | } 667 | unset( $post['terms'], $terms_to_set ); 668 | } 669 | 670 | if ( ! isset( $post['comments'] ) ) 671 | $post['comments'] = array(); 672 | 673 | $post['comments'] = apply_filters( 'wp_import_post_comments', $post['comments'], $post_id, $post ); 674 | 675 | // add/update comments 676 | if ( ! empty( $post['comments'] ) ) { 677 | $num_comments = 0; 678 | $inserted_comments = array(); 679 | foreach ( $post['comments'] as $comment ) { 680 | $comment_id = $comment['comment_id']; 681 | $newcomments[$comment_id]['comment_post_ID'] = $comment_post_ID; 682 | $newcomments[$comment_id]['comment_author'] = $comment['comment_author']; 683 | $newcomments[$comment_id]['comment_author_email'] = $comment['comment_author_email']; 684 | $newcomments[$comment_id]['comment_author_IP'] = $comment['comment_author_IP']; 685 | $newcomments[$comment_id]['comment_author_url'] = $comment['comment_author_url']; 686 | $newcomments[$comment_id]['comment_date'] = $comment['comment_date']; 687 | $newcomments[$comment_id]['comment_date_gmt'] = $comment['comment_date_gmt']; 688 | $newcomments[$comment_id]['comment_content'] = $comment['comment_content']; 689 | $newcomments[$comment_id]['comment_approved'] = $comment['comment_approved']; 690 | $newcomments[$comment_id]['comment_type'] = $comment['comment_type']; 691 | $newcomments[$comment_id]['comment_parent'] = $comment['comment_parent']; 692 | $newcomments[$comment_id]['commentmeta'] = isset( $comment['commentmeta'] ) ? $comment['commentmeta'] : array(); 693 | if ( isset( $this->processed_authors[$comment['comment_user_id']] ) ) 694 | $newcomments[$comment_id]['user_id'] = $this->processed_authors[$comment['comment_user_id']]; 695 | } 696 | ksort( $newcomments ); 697 | 698 | foreach ( $newcomments as $key => $comment ) { 699 | // if this is a new post we can skip the comment_exists() check 700 | if ( ! $post_exists || ! comment_exists( $comment['comment_author'], $comment['comment_date'] ) ) { 701 | if ( isset( $inserted_comments[$comment['comment_parent']] ) ) 702 | $comment['comment_parent'] = $inserted_comments[$comment['comment_parent']]; 703 | $comment = wp_filter_comment( $comment ); 704 | $inserted_comments[$key] = wp_insert_comment( $comment ); 705 | do_action( 'wp_import_insert_comment', $inserted_comments[$key], $comment, $comment_post_ID, $post ); 706 | 707 | foreach( $comment['commentmeta'] as $meta ) { 708 | $value = maybe_unserialize( $meta['value'] ); 709 | add_comment_meta( $inserted_comments[$key], $meta['key'], $value ); 710 | } 711 | 712 | $num_comments++; 713 | } 714 | } 715 | unset( $newcomments, $inserted_comments, $post['comments'] ); 716 | } 717 | 718 | if ( ! isset( $post['postmeta'] ) ) 719 | $post['postmeta'] = array(); 720 | 721 | $post['postmeta'] = apply_filters( 'wp_import_post_meta', $post['postmeta'], $post_id, $post ); 722 | 723 | // add/update post meta 724 | if ( ! empty( $post['postmeta'] ) ) { 725 | foreach ( $post['postmeta'] as $meta ) { 726 | $key = apply_filters( 'import_post_meta_key', $meta['key'], $post_id, $post ); 727 | $value = false; 728 | 729 | if ( '_edit_last' == $key ) { 730 | if ( isset( $this->processed_authors[intval($meta['value'])] ) ) 731 | $value = $this->processed_authors[intval($meta['value'])]; 732 | else 733 | $key = false; 734 | } 735 | 736 | if ( $key ) { 737 | // export gets meta straight from the DB so could have a serialized string 738 | if ( ! $value ) 739 | $value = maybe_unserialize( $meta['value'] ); 740 | 741 | add_post_meta( $post_id, $key, $value ); 742 | do_action( 'import_post_meta', $post_id, $key, $value ); 743 | 744 | // if the post has a featured image, take note of this in case of remap 745 | if ( '_thumbnail_id' == $key ) 746 | $this->featured_images[$post_id] = (int) $value; 747 | } 748 | } 749 | } 750 | } 751 | 752 | unset( $this->posts ); 753 | } 754 | 755 | /** 756 | * Attempt to create a new menu item from import data 757 | * 758 | * Fails for draft, orphaned menu items and those without an associated nav_menu 759 | * or an invalid nav_menu term. If the post type or term object which the menu item 760 | * represents doesn't exist then the menu item will not be imported (waits until the 761 | * end of the import to retry again before discarding). 762 | * 763 | * @param array $item Menu item details from WXR file 764 | */ 765 | function process_menu_item( $item ) { 766 | // skip draft, orphaned menu items 767 | if ( 'draft' == $item['status'] ) 768 | return; 769 | 770 | $menu_slug = false; 771 | if ( isset($item['terms']) ) { 772 | // loop through terms, assume first nav_menu term is correct menu 773 | foreach ( $item['terms'] as $term ) { 774 | if ( 'nav_menu' == $term['domain'] ) { 775 | $menu_slug = $term['slug']; 776 | break; 777 | } 778 | } 779 | } 780 | 781 | // no nav_menu term associated with this menu item 782 | if ( ! $menu_slug ) { 783 | _e( 'Menu item skipped due to missing menu slug', 'wordpress-importer' ); 784 | echo '
'; 785 | return; 786 | } 787 | 788 | $menu_id = term_exists( $menu_slug, 'nav_menu' ); 789 | if ( ! $menu_id ) { 790 | printf( __( 'Menu item skipped due to invalid menu slug: %s', 'wordpress-importer' ), esc_html( $menu_slug ) ); 791 | echo '
'; 792 | return; 793 | } else { 794 | $menu_id = is_array( $menu_id ) ? $menu_id['term_id'] : $menu_id; 795 | } 796 | 797 | foreach ( $item['postmeta'] as $meta ) 798 | $$meta['key'] = $meta['value']; 799 | 800 | if ( 'taxonomy' == $_menu_item_type && isset( $this->processed_terms[intval($_menu_item_object_id)] ) ) { 801 | $_menu_item_object_id = $this->processed_terms[intval($_menu_item_object_id)]; 802 | } else if ( 'post_type' == $_menu_item_type && isset( $this->processed_posts[intval($_menu_item_object_id)] ) ) { 803 | $_menu_item_object_id = $this->processed_posts[intval($_menu_item_object_id)]; 804 | } else if ( 'custom' != $_menu_item_type ) { 805 | // associated object is missing or not imported yet, we'll retry later 806 | $this->missing_menu_items[] = $item; 807 | return; 808 | } 809 | 810 | if ( isset( $this->processed_menu_items[intval($_menu_item_menu_item_parent)] ) ) { 811 | $_menu_item_menu_item_parent = $this->processed_menu_items[intval($_menu_item_menu_item_parent)]; 812 | } else if ( $_menu_item_menu_item_parent ) { 813 | $this->menu_item_orphans[intval($item['post_id'])] = (int) $_menu_item_menu_item_parent; 814 | $_menu_item_menu_item_parent = 0; 815 | } 816 | 817 | // wp_update_nav_menu_item expects CSS classes as a space separated string 818 | $_menu_item_classes = maybe_unserialize( $_menu_item_classes ); 819 | if ( is_array( $_menu_item_classes ) ) 820 | $_menu_item_classes = implode( ' ', $_menu_item_classes ); 821 | 822 | $args = array( 823 | 'menu-item-object-id' => $_menu_item_object_id, 824 | 'menu-item-object' => $_menu_item_object, 825 | 'menu-item-parent-id' => $_menu_item_menu_item_parent, 826 | 'menu-item-position' => intval( $item['menu_order'] ), 827 | 'menu-item-type' => $_menu_item_type, 828 | 'menu-item-title' => $item['post_title'], 829 | 'menu-item-url' => $_menu_item_url, 830 | 'menu-item-description' => $item['post_content'], 831 | 'menu-item-attr-title' => $item['post_excerpt'], 832 | 'menu-item-target' => $_menu_item_target, 833 | 'menu-item-classes' => $_menu_item_classes, 834 | 'menu-item-xfn' => $_menu_item_xfn, 835 | 'menu-item-status' => $item['status'] 836 | ); 837 | 838 | $id = wp_update_nav_menu_item( $menu_id, 0, $args ); 839 | if ( $id && ! is_wp_error( $id ) ) 840 | $this->processed_menu_items[intval($item['post_id'])] = (int) $id; 841 | } 842 | 843 | /** 844 | * If fetching attachments is enabled then attempt to create a new attachment 845 | * 846 | * @param array $post Attachment post details from WXR 847 | * @param string $url URL to fetch attachment from 848 | * @return int|WP_Error Post ID on success, WP_Error otherwise 849 | */ 850 | function process_attachment( $post, $url ) { 851 | if ( ! $this->fetch_attachments ) 852 | return new WP_Error( 'attachment_processing_error', 853 | __( 'Fetching attachments is not enabled', 'wordpress-importer' ) ); 854 | 855 | // if the URL is absolute, but does not contain address, then upload it assuming base_site_url 856 | if ( preg_match( '|^/[\w\W]+$|', $url ) ) 857 | $url = rtrim( $this->base_url, '/' ) . $url; 858 | 859 | $upload = $this->fetch_remote_file( $url, $post ); 860 | if ( is_wp_error( $upload ) ) 861 | return $upload; 862 | 863 | if ( $info = wp_check_filetype( $upload['file'] ) ) 864 | $post['post_mime_type'] = $info['type']; 865 | else 866 | return new WP_Error( 'attachment_processing_error', __('Invalid file type', 'wordpress-importer') ); 867 | 868 | $post['guid'] = $upload['url']; 869 | 870 | // as per wp-admin/includes/upload.php 871 | $post_id = wp_insert_attachment( $post, $upload['file'] ); 872 | wp_update_attachment_metadata( $post_id, wp_generate_attachment_metadata( $post_id, $upload['file'] ) ); 873 | 874 | // remap resized image URLs, works by stripping the extension and remapping the URL stub. 875 | if ( preg_match( '!^image/!', $info['type'] ) ) { 876 | $parts = pathinfo( $url ); 877 | $name = basename( $parts['basename'], ".{$parts['extension']}" ); // PATHINFO_FILENAME in PHP 5.2 878 | 879 | $parts_new = pathinfo( $upload['url'] ); 880 | $name_new = basename( $parts_new['basename'], ".{$parts_new['extension']}" ); 881 | 882 | $this->url_remap[$parts['dirname'] . '/' . $name] = $parts_new['dirname'] . '/' . $name_new; 883 | } 884 | 885 | return $post_id; 886 | } 887 | 888 | /** 889 | * Attempt to download a remote file attachment 890 | * 891 | * @param string $url URL of item to fetch 892 | * @param array $post Attachment details 893 | * @return array|WP_Error Local file location details on success, WP_Error otherwise 894 | */ 895 | function fetch_remote_file( $url, $post ) { 896 | // extract the file name and extension from the url 897 | $file_name = basename( $url ); 898 | 899 | // get placeholder file in the upload dir with a unique, sanitized filename 900 | $upload = wp_upload_bits( $file_name, 0, '', $post['upload_date'] ); 901 | if ( $upload['error'] ) 902 | return new WP_Error( 'upload_dir_error', $upload['error'] ); 903 | 904 | // fetch the remote url and write it to the placeholder file 905 | $headers = wp_get_http( $url, $upload['file'] ); 906 | 907 | // request failed 908 | if ( ! $headers ) { 909 | @unlink( $upload['file'] ); 910 | return new WP_Error( 'import_file_error', __('Remote server did not respond', 'wordpress-importer') ); 911 | } 912 | 913 | // make sure the fetch was successful 914 | if ( $headers['response'] != '200' ) { 915 | @unlink( $upload['file'] ); 916 | return new WP_Error( 'import_file_error', sprintf( __('Remote server returned error response %1$d %2$s', 'wordpress-importer'), esc_html($headers['response']), get_status_header_desc($headers['response']) ) ); 917 | } 918 | 919 | $filesize = filesize( $upload['file'] ); 920 | 921 | if ( isset( $headers['content-length'] ) && $filesize != $headers['content-length'] ) { 922 | @unlink( $upload['file'] ); 923 | return new WP_Error( 'import_file_error', __('Remote file is incorrect size', 'wordpress-importer') ); 924 | } 925 | 926 | if ( 0 == $filesize ) { 927 | @unlink( $upload['file'] ); 928 | return new WP_Error( 'import_file_error', __('Zero size file downloaded', 'wordpress-importer') ); 929 | } 930 | 931 | $max_size = (int) $this->max_attachment_size(); 932 | if ( ! empty( $max_size ) && $filesize > $max_size ) { 933 | @unlink( $upload['file'] ); 934 | return new WP_Error( 'import_file_error', sprintf(__('Remote file is too large, limit is %s', 'wordpress-importer'), size_format($max_size) ) ); 935 | } 936 | 937 | // keep track of the old and new urls so we can substitute them later 938 | $this->url_remap[$url] = $upload['url']; 939 | $this->url_remap[$post['guid']] = $upload['url']; // r13735, really needed? 940 | // keep track of the destination if the remote url is redirected somewhere else 941 | if ( isset($headers['x-final-location']) && $headers['x-final-location'] != $url ) 942 | $this->url_remap[$headers['x-final-location']] = $upload['url']; 943 | 944 | return $upload; 945 | } 946 | 947 | /** 948 | * Attempt to associate posts and menu items with previously missing parents 949 | * 950 | * An imported post's parent may not have been imported when it was first created 951 | * so try again. Similarly for child menu items and menu items which were missing 952 | * the object (e.g. post) they represent in the menu 953 | */ 954 | function backfill_parents() { 955 | global $wpdb; 956 | 957 | // find parents for post orphans 958 | foreach ( $this->post_orphans as $child_id => $parent_id ) { 959 | $local_child_id = $local_parent_id = false; 960 | if ( isset( $this->processed_posts[$child_id] ) ) 961 | $local_child_id = $this->processed_posts[$child_id]; 962 | if ( isset( $this->processed_posts[$parent_id] ) ) 963 | $local_parent_id = $this->processed_posts[$parent_id]; 964 | 965 | if ( $local_child_id && $local_parent_id ) 966 | $wpdb->update( $wpdb->posts, array( 'post_parent' => $local_parent_id ), array( 'ID' => $local_child_id ), '%d', '%d' ); 967 | } 968 | 969 | // all other posts/terms are imported, retry menu items with missing associated object 970 | $missing_menu_items = $this->missing_menu_items; 971 | foreach ( $missing_menu_items as $item ) 972 | $this->process_menu_item( $item ); 973 | 974 | // find parents for menu item orphans 975 | foreach ( $this->menu_item_orphans as $child_id => $parent_id ) { 976 | $local_child_id = $local_parent_id = 0; 977 | if ( isset( $this->processed_menu_items[$child_id] ) ) 978 | $local_child_id = $this->processed_menu_items[$child_id]; 979 | if ( isset( $this->processed_menu_items[$parent_id] ) ) 980 | $local_parent_id = $this->processed_menu_items[$parent_id]; 981 | 982 | if ( $local_child_id && $local_parent_id ) 983 | update_post_meta( $local_child_id, '_menu_item_menu_item_parent', (int) $local_parent_id ); 984 | } 985 | } 986 | 987 | /** 988 | * Use stored mapping information to update old attachment URLs 989 | */ 990 | function backfill_attachment_urls() { 991 | global $wpdb; 992 | // make sure we do the longest urls first, in case one is a substring of another 993 | uksort( $this->url_remap, array(&$this, 'cmpr_strlen') ); 994 | 995 | foreach ( $this->url_remap as $from_url => $to_url ) { 996 | // remap urls in post_content 997 | $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)", $from_url, $to_url) ); 998 | // remap enclosure urls 999 | $result = $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = REPLACE(meta_value, %s, %s) WHERE meta_key='enclosure'", $from_url, $to_url) ); 1000 | } 1001 | } 1002 | 1003 | /** 1004 | * Update _thumbnail_id meta to new, imported attachment IDs 1005 | */ 1006 | function remap_featured_images() { 1007 | // cycle through posts that have a featured image 1008 | foreach ( $this->featured_images as $post_id => $value ) { 1009 | if ( isset( $this->processed_posts[$value] ) ) { 1010 | $new_id = $this->processed_posts[$value]; 1011 | // only update if there's a difference 1012 | if ( $new_id != $value ) 1013 | update_post_meta( $post_id, '_thumbnail_id', $new_id ); 1014 | } 1015 | } 1016 | } 1017 | 1018 | /** 1019 | * Parse a WXR file 1020 | * 1021 | * @param string $file Path to WXR file for parsing 1022 | * @return array Information gathered from the WXR file 1023 | */ 1024 | function parse( $file ) { 1025 | $parser = new WXR_Parser(); 1026 | return $parser->parse( $file ); 1027 | } 1028 | 1029 | // Display import page title 1030 | function header() { 1031 | echo '
'; 1032 | screen_icon(); 1033 | echo '

' . __( 'Import WordPress', 'wordpress-importer' ) . '

'; 1034 | 1035 | $updates = get_plugin_updates(); 1036 | $basename = plugin_basename(__FILE__); 1037 | if ( isset( $updates[$basename] ) ) { 1038 | $update = $updates[$basename]; 1039 | echo '

'; 1040 | printf( __( 'A new version of this importer is available. Please update to version %s to ensure compatibility with newer export files.', 'wordpress-importer' ), $update->update->new_version ); 1041 | echo '

'; 1042 | } 1043 | } 1044 | 1045 | // Close div.wrap 1046 | function footer() { 1047 | echo '
'; 1048 | } 1049 | 1050 | /** 1051 | * Display introductory text and file upload form 1052 | */ 1053 | function greet() { 1054 | echo '
'; 1055 | echo '

'.__( 'Howdy! Upload your WordPress eXtended RSS (WXR) file and we’ll import the posts, pages, comments, custom fields, categories, and tags into this site.', 'wordpress-importer' ).'

'; 1056 | echo '

'.__( 'Choose a WXR (.xml) file to upload, then click Upload file and import.', 'wordpress-importer' ).'

'; 1057 | wp_import_upload_form( 'admin.php?import=wordpress&step=1' ); 1058 | echo '
'; 1059 | } 1060 | 1061 | /** 1062 | * Decide if the given meta key maps to information we will want to import 1063 | * 1064 | * @param string $key The meta key to check 1065 | * @return string|bool The key if we do want to import, false if not 1066 | */ 1067 | function is_valid_meta_key( $key ) { 1068 | // skip attachment metadata since we'll regenerate it from scratch 1069 | // skip _edit_lock as not relevant for import 1070 | if ( in_array( $key, array( '_wp_attached_file', '_wp_attachment_metadata', '_edit_lock' ) ) ) 1071 | return false; 1072 | return $key; 1073 | } 1074 | 1075 | /** 1076 | * Decide whether or not the importer is allowed to create users. 1077 | * Default is true, can be filtered via import_allow_create_users 1078 | * 1079 | * @return bool True if creating users is allowed 1080 | */ 1081 | function allow_create_users() { 1082 | return apply_filters( 'import_allow_create_users', true ); 1083 | } 1084 | 1085 | /** 1086 | * Decide whether or not the importer should attempt to download attachment files. 1087 | * Default is true, can be filtered via import_allow_fetch_attachments. The choice 1088 | * made at the import options screen must also be true, false here hides that checkbox. 1089 | * 1090 | * @return bool True if downloading attachments is allowed 1091 | */ 1092 | function allow_fetch_attachments() { 1093 | return apply_filters( 'import_allow_fetch_attachments', true ); 1094 | } 1095 | 1096 | /** 1097 | * Decide what the maximum file size for downloaded attachments is. 1098 | * Default is 0 (unlimited), can be filtered via import_attachment_size_limit 1099 | * 1100 | * @return int Maximum attachment file size to import 1101 | */ 1102 | function max_attachment_size() { 1103 | return apply_filters( 'import_attachment_size_limit', 0 ); 1104 | } 1105 | 1106 | /** 1107 | * Added to http_request_timeout filter to force timeout at 60 seconds during import 1108 | * @return int 60 1109 | */ 1110 | function bump_request_timeout() { 1111 | return 60; 1112 | } 1113 | 1114 | // return the difference in length between two strings 1115 | function cmpr_strlen( $a, $b ) { 1116 | return strlen($b) - strlen($a); 1117 | } 1118 | } 1119 | 1120 | } // class_exists( 'WP_Importer' ) 1121 | 1122 | function wordpress_importer_init() { 1123 | load_plugin_textdomain( 'wordpress-importer', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); 1124 | 1125 | /** 1126 | * WordPress Importer object for registering the import callback 1127 | * @global WP_Import $wp_import 1128 | */ 1129 | $GLOBALS['wp_import'] = new WP_Import(); 1130 | register_importer( 'wordpress', 'WordPress', __('Import posts, pages, comments, custom fields, categories, and tags from a WordPress export file.', 'wordpress-importer'), array( $GLOBALS['wp_import'], 'dispatch' ) ); 1131 | } 1132 | add_action( 'admin_init', 'wordpress_importer_init' ); 1133 | -------------------------------------------------------------------------------- /demos/demo-1/content.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 27 | 28 | 29 | Dummy 30 | http://wordpress.box/dummy 31 | Just another WordPress site 32 | Sat, 12 Mar 2016 05:35:12 +0000 33 | en-US 34 | 1.2 35 | http://wordpress.box/dummy 36 | http://wordpress.box/dummy 37 | 38 | 1 39 | 40 | 1 41 | 2nav_menu 42 | 3nav_menu 43 | 44 | https://wordpress.org/?v=4.4.2 45 | 46 | 47 | Hello world! 48 | http://wordpress.box/dummy/2016/03/01/hello-world/ 49 | Tue, 01 Mar 2016 06:29:13 +0000 50 | 51 | http://wordpress.box/dummy/?p=1 52 | 53 | 54 | 55 | 1 56 | 57 | 58 | 59 | 60 | 61 | 62 | 0 63 | 0 64 | 65 | 66 | 0 67 | 68 | 69 | 1 70 | 71 | 72 | https://wordpress.org/ 73 | 74 | 75 | 76 | 78 | 79 | 80 | 0 81 | 0 82 | 83 | 84 | 85 | Sample Page 86 | http://wordpress.box/dummy/sample-page/ 87 | Tue, 01 Mar 2016 06:29:13 +0000 88 | 89 | http://wordpress.box/dummy/?page_id=2 90 | 91 | Hi there! I'm a bike messenger by day, aspiring actor by night, and this is my website. I live in Los Angeles, have a great dog named Jack, and I like piña coladas. (And gettin' caught in the rain.) 94 | 95 | ...or something like this: 96 | 97 |
The XYZ Doohickey Company was founded in 1971, and has been providing quality doohickeys to the public ever since. Located in Gotham City, XYZ employs over 2,000 people and does all kinds of awesome things for the Gotham community.
98 | 99 | As a new WordPress user, you should go to your dashboard to delete this page and create new pages for your content. Have fun!]]>
100 | 101 | 2 102 | 103 | 104 | 105 | 106 | 107 | 108 | 0 109 | 0 110 | 111 | 112 | 0 113 | 114 | 115 | 116 | 117 |
118 | 119 | 12705444_1137483649596773_8689597924612318655_n 120 | http://wordpress.box/dummy/12705444_1137483649596773_8689597924612318655_n/ 121 | Tue, 01 Mar 2016 06:30:58 +0000 122 | 123 | http://wordpress.box/dummy/wp-content/uploads/2016/03/12705444_1137483649596773_8689597924612318655_n.jpg 124 | 125 | 126 | 127 | 4 128 | 129 | 130 | 131 | 132 | 133 | 134 | 0 135 | 0 136 | 137 | 138 | 0 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | Home 151 | http://wordpress.box/dummy/2016/03/01/home/ 152 | Tue, 01 Mar 2016 12:29:27 +0000 153 | 154 | http://wordpress.box/dummy/?p=5 155 | 156 | 157 | 158 | 5 159 | 160 | 161 | 162 | 163 | 164 | 165 | 0 166 | 1 167 | 168 | 169 | 0 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | http://wordpress.box/dummy/2016/03/01/6/ 207 | Tue, 01 Mar 2016 12:29:27 +0000 208 | 209 | http://wordpress.box/dummy/?p=6 210 | 211 | 212 | 213 | 6 214 | 215 | 216 | 217 | 218 | 219 | 220 | 0 221 | 2 222 | 223 | 224 | 0 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | Blog 261 | http://wordpress.box/dummy/blog/ 262 | Tue, 01 Mar 2016 13:16:46 +0000 263 | 264 | http://wordpress.box/dummy/?page_id=7 265 | 266 | 267 | 268 | 7 269 | 270 | 271 | 272 | 273 | 274 | 275 | 0 276 | 0 277 | 278 | 279 | 0 280 | 281 | 282 | 283 | 284 | 285 | 286 | Home 287 | http://wordpress.box/dummy/home/ 288 | Tue, 01 Mar 2016 13:16:53 +0000 289 | 290 | http://wordpress.box/dummy/?page_id=9 291 | 292 | 293 | 294 | 9 295 | 296 | 297 | 298 | 299 | 300 | 301 | 0 302 | 0 303 | 304 | 305 | 0 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | http://wordpress.box/dummy/2016/03/01/11/ 314 | Tue, 01 Mar 2016 13:26:56 +0000 315 | 316 | http://wordpress.box/dummy/?p=11 317 | 318 | 319 | 320 | 11 321 | 322 | 323 | 324 | 325 | 326 | 327 | 0 328 | 5 329 | 330 | 331 | 0 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | Home 368 | http://wordpress.box/dummy/2016/03/01/home-2/ 369 | Tue, 01 Mar 2016 13:26:56 +0000 370 | 371 | http://wordpress.box/dummy/?p=12 372 | 373 | 374 | 375 | 12 376 | 377 | 378 | 379 | 380 | 381 | 382 | 0 383 | 1 384 | 385 | 386 | 0 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | http://wordpress.box/dummy/2016/03/01/13/ 424 | Tue, 01 Mar 2016 13:26:56 +0000 425 | 426 | http://wordpress.box/dummy/?p=13 427 | 428 | 429 | 430 | 13 431 | 432 | 433 | 434 | 435 | 436 | 437 | 0 438 | 2 439 | 440 | 441 | 0 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | http://wordpress.box/dummy/2016/03/01/14/ 479 | Tue, 01 Mar 2016 13:26:56 +0000 480 | 481 | http://wordpress.box/dummy/?p=14 482 | 483 | 484 | 485 | 14 486 | 487 | 488 | 489 | 490 | 491 | 492 | 0 493 | 3 494 | 495 | 496 | 0 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | http://wordpress.box/dummy/2016/03/01/15/ 534 | Tue, 01 Mar 2016 13:26:56 +0000 535 | 536 | http://wordpress.box/dummy/?p=15 537 | 538 | 539 | 540 | 15 541 | 542 | 543 | 544 | 545 | 546 | 547 | 0 548 | 4 549 | 550 | 551 | 0 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 |
587 |
588 | -------------------------------------------------------------------------------- /demos/demo-1/options.txt: -------------------------------------------------------------------------------- 1 | eNq1V9tu4zYQfS_QfyCclxaNnUi241jrBk03XbToBduiiz4KlERZRGhSJam4xlwiH9Tf6Jf1kBIVWYmD7kOBJKA0M2cO56rQZL5KPpokipNJxWjBdGrsQbDJG5Oskok_p5F7WuOJW5YKtVXuGQaLS3-IBpLUaipNTTWTNmhFHVhJH3iuZHgdu4PzWyplT_uNVr1GRvP7rVaNLALG3GtEvcaQ3MLL1r0Mri3NbcplCR2azJOPPLlsDyZZJBNJd97_dTL5SeXU8pYrJIF2dOVuQUo63dEav_qe6aDiUU1yBdfR_O6cvGtk7iCoILeIh90hXCLnZJNpcnHzQfI_G0beKqHk4Zy8pYKXSktOyfXq18mbR55EL_DCEZpizCkKnOpKSTais4D0qzgm86v1NF5E6-n6ehV1LI7ez-N15D3HL3heJpPvdpQ_c70Irpl8YELVY-_LqD1_U_AtpwIFVptZrnYdAdPUtdLWS-1ADB6PR6lzGD5_XVXNl5D9wQjKjDj_XFyLAzE7BOeclIL9xTPBSMEM30pibFNwRWxFbffKEASb1JpLS6gsyJ5lMwK0vdL3wfxA9txWJBccLg2xipSNKLlcMA7jOmBLxgoD24rhtSYH1fhXTj3XjFrHLtPOR6lxa5NravPqnHCZC7CSW-JryLZcJ9wUQTKeE-wYbSyHV_9cXD5VE-i6diO4w37g2MVCKHXvsNz9aCCpWamZqT7_bN8GDHEseYFrebM9FwK-SC0YNaDurw1QmJlGWDMLLd53UX3QfFuFPkKe5miYt-E1-edvEl9GV2RDSQXXX08qa-vk4sIR29F9Pas1e-BsPytYDhJwtWNt1m9-hMrPdHNBb2bkjrUVVZDs8AyL7rhsxEwyO7m59WfygxF050w9pctkkmEWpJbbdqbE6Nxf2N6QWwRzgwElb76FwubCH0NvexuELde8Du0fuVwi3tQ3_3O5tR3xCVW3uahb3suO9_PpuAwTsL0XN7WghzRrrHVXyzBkoBdCRX19pZmV6WDg_IadMDmhJri8bwsgmZw54XSvaV23I9HNBqrzij8w85QGoAS0XjiKd6fiaPcqx1cLIHFHyaBssC0KVlJUbJptu_vHfn_Ei2M1o3J0WWoqZPNZEDqdWhmLKDwEudtSW6Ey2OWY2XrEcyhKqcm7KTW47JGGemAaiRiqoPZCejp-bsam7UbuWZ7QajtzyHUgNW7VLV9Zde9ozjLMjS7hfVKR05PjvuxtTqwq7OzfUcq2X4-vwc4DrA0mXCfWkFvMwGGYnJ_CVvQ2wF28zPZO8ywT7FNgC2fibVwwu3wBFpXxHk3PMEntf1wwXvZ7_MnI78HVIO0Y3Cm-JJo-20v38YWXqFa-7b5ZXkk4jt-r3fie8HAWau2IFFwiXlg-rbzJiVxcQ-c2U40lH8wIFgE4o040bcwIeN0BM3wZncy3CyC-D0oluBoHEJ1zVo-EI9ZbgHvs-YnKx4ZuEOcXWJfHohFwpoR9rZjea55jkIxwrx3jI0mf-lWLm3OdCzYtlBC-Cx49GexLoUJurn0tUJRdEYqmlz_NJjeU9DajX8RxdL70P5ez9ZfPLfpv7vjaE2VTk1NQqBth2NRlDhOdF1O_STB--M7FfDj-UMnY0jJ1fxynDGXXLlNXpsf_DrSyeD4c_mEpUSnbGXb55vFf6okWtA -------------------------------------------------------------------------------- /demos/demo-1/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AminulBD/dt-demo-importer/7eeb0c02235a2ecca6c37e042018dac605bd0374/demos/demo-1/screenshot.png -------------------------------------------------------------------------------- /demos/demo-2/content.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 27 | 28 | 29 | Dummy 30 | http://wordpress.box/dummy 31 | Just another WordPress site 32 | Tue, 01 Mar 2016 06:31:33 +0000 33 | en-US 34 | 1.2 35 | http://wordpress.box/dummy 36 | http://wordpress.box/dummy 37 | 38 | 1 39 | 40 | 1 41 | 42 | https://wordpress.org/?v=4.4.2 43 | 44 | 45 | Hello world! 46 | http://wordpress.box/dummy/2016/03/01/hello-world/ 47 | Tue, 01 Mar 2016 06:29:13 +0000 48 | 49 | http://wordpress.box/dummy/?p=1 50 | 51 | 52 | 53 | 1 54 | 55 | 56 | 57 | 58 | 59 | 60 | 0 61 | 0 62 | 63 | 64 | 0 65 | 66 | 67 | 1 68 | 69 | 70 | https://wordpress.org/ 71 | 72 | 73 | 74 | 76 | 77 | 78 | 0 79 | 0 80 | 81 | 82 | 83 | Sample Page 84 | http://wordpress.box/dummy/sample-page/ 85 | Tue, 01 Mar 2016 06:29:13 +0000 86 | 87 | http://wordpress.box/dummy/?page_id=2 88 | 89 | Hi there! I'm a bike messenger by day, aspiring actor by night, and this is my website. I live in Los Angeles, have a great dog named Jack, and I like piña coladas. (And gettin' caught in the rain.) 92 | 93 | ...or something like this: 94 | 95 |
The XYZ Doohickey Company was founded in 1971, and has been providing quality doohickeys to the public ever since. Located in Gotham City, XYZ employs over 2,000 people and does all kinds of awesome things for the Gotham community.
96 | 97 | As a new WordPress user, you should go to your dashboard to delete this page and create new pages for your content. Have fun!]]>
98 | 99 | 2 100 | 101 | 102 | 103 | 104 | 105 | 106 | 0 107 | 0 108 | 109 | 110 | 0 111 | 112 | 113 | 114 | 115 |
116 | 117 | 12705444_1137483649596773_8689597924612318655_n 118 | http://wordpress.box/dummy/12705444_1137483649596773_8689597924612318655_n/ 119 | Tue, 01 Mar 2016 06:30:58 +0000 120 | 121 | http://wordpress.box/dummy/wp-content/uploads/2016/03/12705444_1137483649596773_8689597924612318655_n.jpg 122 | 123 | 124 | 125 | 4 126 | 127 | 128 | 129 | 130 | 131 | 132 | 0 133 | 0 134 | 135 | 136 | 0 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 |
148 |
149 | -------------------------------------------------------------------------------- /demos/demo-2/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AminulBD/dt-demo-importer/7eeb0c02235a2ecca6c37e042018dac605bd0374/demos/demo-2/screenshot.png -------------------------------------------------------------------------------- /demos/demo-3/content.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 27 | 28 | 29 | Dummy 30 | http://wordpress.box/dummy 31 | Just another WordPress site 32 | Tue, 01 Mar 2016 06:31:33 +0000 33 | en-US 34 | 1.2 35 | http://wordpress.box/dummy 36 | http://wordpress.box/dummy 37 | 38 | 1 39 | 40 | 1 41 | 42 | https://wordpress.org/?v=4.4.2 43 | 44 | 45 | Hello world! 46 | http://wordpress.box/dummy/2016/03/01/hello-world/ 47 | Tue, 01 Mar 2016 06:29:13 +0000 48 | 49 | http://wordpress.box/dummy/?p=1 50 | 51 | 52 | 53 | 1 54 | 55 | 56 | 57 | 58 | 59 | 60 | 0 61 | 0 62 | 63 | 64 | 0 65 | 66 | 67 | 1 68 | 69 | 70 | https://wordpress.org/ 71 | 72 | 73 | 74 | 76 | 77 | 78 | 0 79 | 0 80 | 81 | 82 | 83 | Sample Page 84 | http://wordpress.box/dummy/sample-page/ 85 | Tue, 01 Mar 2016 06:29:13 +0000 86 | 87 | http://wordpress.box/dummy/?page_id=2 88 | 89 | Hi there! I'm a bike messenger by day, aspiring actor by night, and this is my website. I live in Los Angeles, have a great dog named Jack, and I like piña coladas. (And gettin' caught in the rain.) 92 | 93 | ...or something like this: 94 | 95 |
The XYZ Doohickey Company was founded in 1971, and has been providing quality doohickeys to the public ever since. Located in Gotham City, XYZ employs over 2,000 people and does all kinds of awesome things for the Gotham community.
96 | 97 | As a new WordPress user, you should go to your dashboard to delete this page and create new pages for your content. Have fun!]]>
98 | 99 | 2 100 | 101 | 102 | 103 | 104 | 105 | 106 | 0 107 | 0 108 | 109 | 110 | 0 111 | 112 | 113 | 114 | 115 |
116 | 117 | 12705444_1137483649596773_8689597924612318655_n 118 | http://wordpress.box/dummy/12705444_1137483649596773_8689597924612318655_n/ 119 | Tue, 01 Mar 2016 06:30:58 +0000 120 | 121 | http://wordpress.box/dummy/wp-content/uploads/2016/03/12705444_1137483649596773_8689597924612318655_n.jpg 122 | 123 | 124 | 125 | 4 126 | 127 | 128 | 129 | 130 | 131 | 132 | 0 133 | 0 134 | 135 | 136 | 0 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 |
148 |
149 | -------------------------------------------------------------------------------- /demos/demo-3/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AminulBD/dt-demo-importer/7eeb0c02235a2ecca6c37e042018dac605bd0374/demos/demo-3/screenshot.png -------------------------------------------------------------------------------- /demos/demo-4/content.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 27 | 28 | 29 | Dummy 30 | http://wordpress.box/dummy 31 | Just another WordPress site 32 | Tue, 01 Mar 2016 06:31:33 +0000 33 | en-US 34 | 1.2 35 | http://wordpress.box/dummy 36 | http://wordpress.box/dummy 37 | 38 | 1 39 | 40 | 1 41 | 42 | https://wordpress.org/?v=4.4.2 43 | 44 | 45 | Hello world! 46 | http://wordpress.box/dummy/2016/03/01/hello-world/ 47 | Tue, 01 Mar 2016 06:29:13 +0000 48 | 49 | http://wordpress.box/dummy/?p=1 50 | 51 | 52 | 53 | 1 54 | 55 | 56 | 57 | 58 | 59 | 60 | 0 61 | 0 62 | 63 | 64 | 0 65 | 66 | 67 | 1 68 | 69 | 70 | https://wordpress.org/ 71 | 72 | 73 | 74 | 76 | 77 | 78 | 0 79 | 0 80 | 81 | 82 | 83 | Sample Page 84 | http://wordpress.box/dummy/sample-page/ 85 | Tue, 01 Mar 2016 06:29:13 +0000 86 | 87 | http://wordpress.box/dummy/?page_id=2 88 | 89 | Hi there! I'm a bike messenger by day, aspiring actor by night, and this is my website. I live in Los Angeles, have a great dog named Jack, and I like piña coladas. (And gettin' caught in the rain.) 92 | 93 | ...or something like this: 94 | 95 |
The XYZ Doohickey Company was founded in 1971, and has been providing quality doohickeys to the public ever since. Located in Gotham City, XYZ employs over 2,000 people and does all kinds of awesome things for the Gotham community.
96 | 97 | As a new WordPress user, you should go to your dashboard to delete this page and create new pages for your content. Have fun!]]>
98 | 99 | 2 100 | 101 | 102 | 103 | 104 | 105 | 106 | 0 107 | 0 108 | 109 | 110 | 0 111 | 112 | 113 | 114 | 115 |
116 | 117 | 12705444_1137483649596773_8689597924612318655_n 118 | http://wordpress.box/dummy/12705444_1137483649596773_8689597924612318655_n/ 119 | Tue, 01 Mar 2016 06:30:58 +0000 120 | 121 | http://wordpress.box/dummy/wp-content/uploads/2016/03/12705444_1137483649596773_8689597924612318655_n.jpg 122 | 123 | 124 | 125 | 4 126 | 127 | 128 | 129 | 130 | 131 | 132 | 0 133 | 0 134 | 135 | 136 | 0 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 |
148 |
149 | -------------------------------------------------------------------------------- /demos/demo-4/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AminulBD/dt-demo-importer/7eeb0c02235a2ecca6c37e042018dac605bd0374/demos/demo-4/screenshot.png -------------------------------------------------------------------------------- /init.php: -------------------------------------------------------------------------------- 1 | wp_normalize_path( $basename ), 17 | 'dir' => wp_normalize_path( $dir ), 18 | 'uri' => $uri 19 | ) ); 20 | } 21 | } 22 | 23 | /** 24 | * Importer constants 25 | */ 26 | $get_path = dt_importer_get_path_locate(); 27 | 28 | define( 'DT_IMPORTER_VER' , '1.0.0' ); 29 | define( 'DT_IMPORTER_DIR' , $get_path['dir'] ); 30 | define( 'DT_IMPORTER_URI' , $get_path['uri'] ); 31 | define( 'DT_IMPORTER_CONTENT_DIR' , DT_IMPORTER_DIR . '/demos/' ); 32 | define( 'DT_IMPORTER_CONTENT_URI' , DT_IMPORTER_URI . '/demos/' ); 33 | 34 | 35 | 36 | /** 37 | * Scripts and styles for admin 38 | */ 39 | function dt_importer_enqueue_scripts() { 40 | 41 | wp_enqueue_script( 'dt-importer', DT_IMPORTER_URI . '/assets/js/dt-importer.js', array( 'jquery' ), DT_IMPORTER_VER, true); 42 | wp_enqueue_style( 'dt-importer-css', DT_IMPORTER_URI . '/assets/css/dt-importer.css', null, DT_IMPORTER_VER); 43 | } 44 | 45 | add_action( 'admin_enqueue_scripts', 'dt_importer_enqueue_scripts' ); 46 | 47 | /** 48 | * 49 | * Decode string for backup options (Source from codestar) 50 | * 51 | * @since 1.0.0 52 | * @version 1.0.0 53 | * 54 | */ 55 | if ( ! function_exists( 'cs_decode_string' ) ) { 56 | function cs_decode_string( $string ) { 57 | return unserialize( gzuncompress( stripslashes( call_user_func( 'base'. '64' .'_decode', rtrim( strtr( $string, '-_', '+/' ), '=' ) ) ) ) ); 58 | } 59 | } 60 | 61 | /** 62 | * Load Importer 63 | */ 64 | require_once DT_IMPORTER_DIR . '/classes/abstract.class.php'; 65 | require_once DT_IMPORTER_DIR . '/classes/importer.class.php'; 66 | -------------------------------------------------------------------------------- /licence.txt: -------------------------------------------------------------------------------- 1 | DT Demo Importer for WordPress themes 2 | Copyright 2014 Franklin Gitonga 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | 18 | Last Updated: 18/10/2014 19 | 20 | =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 21 | 22 | GNU GENERAL PUBLIC LICENSE 23 | Version 2, June 1991 24 | 25 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 26 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 27 | Everyone is permitted to copy and distribute verbatim copies 28 | of this license document, but changing it is not allowed. 29 | 30 | Preamble 31 | 32 | The licenses for most software are designed to take away your 33 | freedom to share and change it. By contrast, the GNU General Public 34 | License is intended to guarantee your freedom to share and change free 35 | software--to make sure the software is free for all its users. This 36 | General Public License applies to most of the Free Software 37 | Foundation's software and to any other program whose authors commit to 38 | using it. (Some other Free Software Foundation software is covered by 39 | the GNU Lesser General Public License instead.) You can apply it to 40 | your programs, too. 41 | 42 | When we speak of free software, we are referring to freedom, not 43 | price. Our General Public Licenses are designed to make sure that you 44 | have the freedom to distribute copies of free software (and charge for 45 | this service if you wish), that you receive source code or can get it 46 | if you want it, that you can change the software or use pieces of it 47 | in new free programs; and that you know you can do these things. 48 | 49 | To protect your rights, we need to make restrictions that forbid 50 | anyone to deny you these rights or to ask you to surrender the rights. 51 | These restrictions translate to certain responsibilities for you if you 52 | distribute copies of the software, or if you modify it. 53 | 54 | For example, if you distribute copies of such a program, whether 55 | gratis or for a fee, you must give the recipients all the rights that 56 | you have. You must make sure that they, too, receive or can get the 57 | source code. And you must show them these terms so they know their 58 | rights. 59 | 60 | We protect your rights with two steps: (1) copyright the software, and 61 | (2) offer you this license which gives you legal permission to copy, 62 | distribute and/or modify the software. 63 | 64 | Also, for each author's protection and ours, we want to make certain 65 | that everyone understands that there is no warranty for this free 66 | software. If the software is modified by someone else and passed on, we 67 | want its recipients to know that what they have is not the original, so 68 | that any problems introduced by others will not reflect on the original 69 | authors' reputations. 70 | 71 | Finally, any free program is threatened constantly by software 72 | patents. We wish to avoid the danger that redistributors of a free 73 | program will individually obtain patent licenses, in effect making the 74 | program proprietary. To prevent this, we have made it clear that any 75 | patent must be licensed for everyone's free use or not licensed at all. 76 | 77 | The precise terms and conditions for copying, distribution and 78 | modification follow. 79 | 80 | GNU GENERAL PUBLIC LICENSE 81 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 82 | 83 | 0. This License applies to any program or other work which contains 84 | a notice placed by the copyright holder saying it may be distributed 85 | under the terms of this General Public License. The "Program", below, 86 | refers to any such program or work, and a "work based on the Program" 87 | means either the Program or any derivative work under copyright law: 88 | that is to say, a work containing the Program or a portion of it, 89 | either verbatim or with modifications and/or translated into another 90 | language. (Hereinafter, translation is included without limitation in 91 | the term "modification".) Each licensee is addressed as "you". 92 | 93 | Activities other than copying, distribution and modification are not 94 | covered by this License; they are outside its scope. The act of 95 | running the Program is not restricted, and the output from the Program 96 | is covered only if its contents constitute a work based on the 97 | Program (independent of having been made by running the Program). 98 | Whether that is true depends on what the Program does. 99 | 100 | 1. You may copy and distribute verbatim copies of the Program's 101 | source code as you receive it, in any medium, provided that you 102 | conspicuously and appropriately publish on each copy an appropriate 103 | copyright notice and disclaimer of warranty; keep intact all the 104 | notices that refer to this License and to the absence of any warranty; 105 | and give any other recipients of the Program a copy of this License 106 | along with the Program. 107 | 108 | You may charge a fee for the physical act of transferring a copy, and 109 | you may at your option offer warranty protection in exchange for a fee. 110 | 111 | 2. You may modify your copy or copies of the Program or any portion 112 | of it, thus forming a work based on the Program, and copy and 113 | distribute such modifications or work under the terms of Section 1 114 | above, provided that you also meet all of these conditions: 115 | 116 | a) You must cause the modified files to carry prominent notices 117 | stating that you changed the files and the date of any change. 118 | 119 | b) You must cause any work that you distribute or publish, that in 120 | whole or in part contains or is derived from the Program or any 121 | part thereof, to be licensed as a whole at no charge to all third 122 | parties under the terms of this License. 123 | 124 | c) If the modified program normally reads commands interactively 125 | when run, you must cause it, when started running for such 126 | interactive use in the most ordinary way, to print or display an 127 | announcement including an appropriate copyright notice and a 128 | notice that there is no warranty (or else, saying that you provide 129 | a warranty) and that users may redistribute the program under 130 | these conditions, and telling the user how to view a copy of this 131 | License. (Exception: if the Program itself is interactive but 132 | does not normally print such an announcement, your work based on 133 | the Program is not required to print an announcement.) 134 | 135 | These requirements apply to the modified work as a whole. If 136 | identifiable sections of that work are not derived from the Program, 137 | and can be reasonably considered independent and separate works in 138 | themselves, then this License, and its terms, do not apply to those 139 | sections when you distribute them as separate works. But when you 140 | distribute the same sections as part of a whole which is a work based 141 | on the Program, the distribution of the whole must be on the terms of 142 | this License, whose permissions for other licensees extend to the 143 | entire whole, and thus to each and every part regardless of who wrote it. 144 | 145 | Thus, it is not the intent of this section to claim rights or contest 146 | your rights to work written entirely by you; rather, the intent is to 147 | exercise the right to control the distribution of derivative or 148 | collective works based on the Program. 149 | 150 | In addition, mere aggregation of another work not based on the Program 151 | with the Program (or with a work based on the Program) on a volume of 152 | a storage or distribution medium does not bring the other work under 153 | the scope of this License. 154 | 155 | 3. You may copy and distribute the Program (or a work based on it, 156 | under Section 2) in object code or executable form under the terms of 157 | Sections 1 and 2 above provided that you also do one of the following: 158 | 159 | a) Accompany it with the complete corresponding machine-readable 160 | source code, which must be distributed under the terms of Sections 161 | 1 and 2 above on a medium customarily used for software interchange; or, 162 | 163 | b) Accompany it with a written offer, valid for at least three 164 | years, to give any third party, for a charge no more than your 165 | cost of physically performing source distribution, a complete 166 | machine-readable copy of the corresponding source code, to be 167 | distributed under the terms of Sections 1 and 2 above on a medium 168 | customarily used for software interchange; or, 169 | 170 | c) Accompany it with the information you received as to the offer 171 | to distribute corresponding source code. (This alternative is 172 | allowed only for noncommercial distribution and only if you 173 | received the program in object code or executable form with such 174 | an offer, in accord with Subsection b above.) 175 | 176 | The source code for a work means the preferred form of the work for 177 | making modifications to it. For an executable work, complete source 178 | code means all the source code for all modules it contains, plus any 179 | associated interface definition files, plus the scripts used to 180 | control compilation and installation of the executable. However, as a 181 | special exception, the source code distributed need not include 182 | anything that is normally distributed (in either source or binary 183 | form) with the major components (compiler, kernel, and so on) of the 184 | operating system on which the executable runs, unless that component 185 | itself accompanies the executable. 186 | 187 | If distribution of executable or object code is made by offering 188 | access to copy from a designated place, then offering equivalent 189 | access to copy the source code from the same place counts as 190 | distribution of the source code, even though third parties are not 191 | compelled to copy the source along with the object code. 192 | 193 | 4. You may not copy, modify, sublicense, or distribute the Program 194 | except as expressly provided under this License. Any attempt 195 | otherwise to copy, modify, sublicense or distribute the Program is 196 | void, and will automatically terminate your rights under this License. 197 | However, parties who have received copies, or rights, from you under 198 | this License will not have their licenses terminated so long as such 199 | parties remain in full compliance. 200 | 201 | 5. You are not required to accept this License, since you have not 202 | signed it. However, nothing else grants you permission to modify or 203 | distribute the Program or its derivative works. These actions are 204 | prohibited by law if you do not accept this License. Therefore, by 205 | modifying or distributing the Program (or any work based on the 206 | Program), you indicate your acceptance of this License to do so, and 207 | all its terms and conditions for copying, distributing or modifying 208 | the Program or works based on it. 209 | 210 | 6. Each time you redistribute the Program (or any work based on the 211 | Program), the recipient automatically receives a license from the 212 | original licensor to copy, distribute or modify the Program subject to 213 | these terms and conditions. You may not impose any further 214 | restrictions on the recipients' exercise of the rights granted herein. 215 | You are not responsible for enforcing compliance by third parties to 216 | this License. 217 | 218 | 7. If, as a consequence of a court judgment or allegation of patent 219 | infringement or for any other reason (not limited to patent issues), 220 | conditions are imposed on you (whether by court order, agreement or 221 | otherwise) that contradict the conditions of this License, they do not 222 | excuse you from the conditions of this License. If you cannot 223 | distribute so as to satisfy simultaneously your obligations under this 224 | License and any other pertinent obligations, then as a consequence you 225 | may not distribute the Program at all. For example, if a patent 226 | license would not permit royalty-free redistribution of the Program by 227 | all those who receive copies directly or indirectly through you, then 228 | the only way you could satisfy both it and this License would be to 229 | refrain entirely from distribution of the Program. 230 | 231 | If any portion of this section is held invalid or unenforceable under 232 | any particular circumstance, the balance of the section is intended to 233 | apply and the section as a whole is intended to apply in other 234 | circumstances. 235 | 236 | It is not the purpose of this section to induce you to infringe any 237 | patents or other property right claims or to contest validity of any 238 | such claims; this section has the sole purpose of protecting the 239 | integrity of the free software distribution system, which is 240 | implemented by public license practices. Many people have made 241 | generous contributions to the wide range of software distributed 242 | through that system in reliance on consistent application of that 243 | system; it is up to the author/donor to decide if he or she is willing 244 | to distribute software through any other system and a licensee cannot 245 | impose that choice. 246 | 247 | This section is intended to make thoroughly clear what is believed to 248 | be a consequence of the rest of this License. 249 | 250 | 8. If the distribution and/or use of the Program is restricted in 251 | certain countries either by patents or by copyrighted interfaces, the 252 | original copyright holder who places the Program under this License 253 | may add an explicit geographical distribution limitation excluding 254 | those countries, so that distribution is permitted only in or among 255 | countries not thus excluded. In such case, this License incorporates 256 | the limitation as if written in the body of this License. 257 | 258 | 9. The Free Software Foundation may publish revised and/or new versions 259 | of the General Public License from time to time. Such new versions will 260 | be similar in spirit to the present version, but may differ in detail to 261 | address new problems or concerns. 262 | 263 | Each version is given a distinguishing version number. If the Program 264 | specifies a version number of this License which applies to it and "any 265 | later version", you have the option of following the terms and conditions 266 | either of that version or of any later version published by the Free 267 | Software Foundation. If the Program does not specify a version number of 268 | this License, you may choose any version ever published by the Free Software 269 | Foundation. 270 | 271 | 10. If you wish to incorporate parts of the Program into other free 272 | programs whose distribution conditions are different, write to the author 273 | to ask for permission. For software which is copyrighted by the Free 274 | Software Foundation, write to the Free Software Foundation; we sometimes 275 | make exceptions for this. Our decision will be guided by the two goals 276 | of preserving the free status of all derivatives of our free software and 277 | of promoting the sharing and reuse of software generally. 278 | 279 | NO WARRANTY 280 | 281 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 282 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 283 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 284 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 285 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 286 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 287 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 288 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 289 | REPAIR OR CORRECTION. 290 | 291 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 292 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 293 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 294 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 295 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 296 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 297 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 298 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 299 | POSSIBILITY OF SUCH DAMAGES. 300 | 301 | END OF TERMS AND CONDITIONS 302 | 303 | How to Apply These Terms to Your New Programs 304 | 305 | If you develop a new program, and you want it to be of the greatest 306 | possible use to the public, the best way to achieve this is to make it 307 | free software which everyone can redistribute and change under these terms. 308 | 309 | To do so, attach the following notices to the program. It is safest 310 | to attach them to the start of each source file to most effectively 311 | convey the exclusion of warranty; and each file should have at least 312 | the "copyright" line and a pointer to where the full notice is found. 313 | 314 | 315 | Copyright (C) 316 | 317 | This program is free software; you can redistribute it and/or modify 318 | it under the terms of the GNU General Public License as published by 319 | the Free Software Foundation; either version 2 of the License, or 320 | (at your option) any later version. 321 | 322 | This program is distributed in the hope that it will be useful, 323 | but WITHOUT ANY WARRANTY; without even the implied warranty of 324 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 325 | GNU General Public License for more details. 326 | 327 | You should have received a copy of the GNU General Public License along 328 | with this program; if not, write to the Free Software Foundation, Inc., 329 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 330 | 331 | Also add information on how to contact you by electronic and paper mail. 332 | 333 | If the program is interactive, make it output a short notice like this 334 | when it starts in an interactive mode: 335 | 336 | Gnomovision version 69, Copyright (C) year name of author 337 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 338 | This is free software, and you are welcome to redistribute it 339 | under certain conditions; type `show c' for details. 340 | 341 | The hypothetical commands `show w' and `show c' should show the appropriate 342 | parts of the General Public License. Of course, the commands you use may 343 | be called something other than `show w' and `show c'; they could even be 344 | mouse-clicks or menu items--whatever suits your program. 345 | 346 | You should also get your employer (if you work as a programmer) or your 347 | school, if any, to sign a "copyright disclaimer" for the program, if 348 | necessary. Here is a sample; alter the names: 349 | 350 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 351 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 352 | 353 | , 1 April 1989 354 | Ty Coon, President of Vice 355 | 356 | This General Public License does not permit incorporating your program into 357 | proprietary programs. If your program is a subroutine library, you may 358 | consider it more useful to permit linking proprietary applications with the 359 | library. If this is what you want to do, use the GNU Lesser General 360 | Public License instead of this License. 361 | 362 | WRITTEN OFFER 363 | 364 | The source code for any program binaries or compressed scripts that are 365 | included with DT Demo Importer for WordPress themes can be freely obtained at the following URL: 366 | 367 | https://github.com/AminulBD/dt-demo-importer/ -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # DT Demo Importer for WordPress themes 2 | A One Click Demo Installer Class for WordPress Themes. This class developed for creating a quick installer for wordpress. 3 | 4 | 5 | # Quick Usage 6 | 7 | **Place this code in functions.php** 8 | ````php 9 | /** 10 | * Initialize DT Importer 11 | */ 12 | $settings = array( 13 | 'menu_parent' => 'tools.php', 14 | 'menu_title' => __('Demo Importer', 'dt-importer'), 15 | 'menu_type' => 'add_submenu_page', 16 | 'menu_slug' => 'dt_demo_importer', 17 | ); 18 | $options = array( 19 | 'demo-1' => array( 20 | 'title' => __('Demo 1', 'dt-importer'), 21 | 'preview_url' => 'https://www.google.com/', 22 | 'front_page' => 'Home', 23 | 'blog_page' => 'Blog', 24 | 'menus' => array( 25 | 'primary' => 'Primary', // Menu Location and Title 26 | 'secondary' => 'Secondary', 27 | ) 28 | ), 29 | 'demo-2' => array( 30 | 'title' => __('Demo 2', 'dt-importer'), 31 | 'preview_url' => 'https://www.yahoo.com/', 32 | 'front_page' => 'Home', 33 | 'blog_page' => 'Blog', 34 | 'menus' => array( 35 | 'primary' => 'Primary', 36 | 'secondary' => 'Secondary', 37 | ) 38 | ), 39 | 'demo-3' => array( 40 | 'title' => __('Demo 3', 'dt-importer'), 41 | 'preview_url' => 'https://www.google.com/', 42 | 'front_page' => 'Home', 43 | 'blog_page' => 'Blog', 44 | 'menus' => array( 45 | 'primary' => 'Primary', 46 | 'secondary' => 'Secondary', 47 | ) 48 | ), 49 | ); 50 | DT_Demo_Importer::instance( $settings, $options ); 51 | 52 | ```` 53 | 54 | **Create Folder by id in ````dt_importer/demos/```` by same id** 55 | ````php 56 | demos 57 | - demo-1 58 | - content.xml // WP Exported Data 59 | - options.txt // Codestar Exported Options data 60 | - screenshot.php // Preview Image 61 | - demo-2 62 | - content.xml // WP Exported Data 63 | - options.txt // Codestart Exported Options data 64 | - screenshot.php // Preview Image 65 | - demo-3 66 | - content.xml // WP Exported Data 67 | - options.txt // Codestar Exported Options data 68 | - screenshot.php // Preview Image 69 | ```` 70 | 71 | Now go to the Tools >> Demo Importer :) 72 | 73 | # Few screenshots 74 | ![Dashboard](http://i.imgur.com/u8oknuS.jpg) 75 | 76 | # Under Development 77 | * This class only import codestar settings only and planned to support others framework (Like: redux, option tree) 78 | * Planned to support widget import. 79 | 80 | # create `content.xml` and `options.txt` file 81 | You can create content.xml by exporting your content from the WordPress dashboard (Dashboard > Tools > Export) and you can options string from backup field on the codestar option panel. 82 | # Credits 83 | * [Codestar](https://github.com/Codestar/codestar-framework) 84 | * [FrankM1](https://github.com/FrankM1/radium-one-click-demo-install) 85 | 86 | # Licence 87 | GPL V2+ 88 | --------------------------------------------------------------------------------