WordPress.org

Make WordPress Core

Ticket #16460: wpcat2tag-importer.php

File wpcat2tag-importer.php, 12.2 KB (added by sillybean, 3 years ago)

Added a couple of checks to exclude nav menus

Line 
1<?php
2/*
3Plugin Name: Categories, Tags, Formats, and Taxonomy Converter
4Plugin URI: http://wordpress.org/extend/plugins/wpcat2tag-importer/
5Description: Convert existing categories to tags or tags to categories, selectively.
6Author: wordpressdotorg
7Author URI: http://wordpress.org/
8Version: 0.6
9License: GPL version 2 or later - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10*/
11
12/* == Todo ==
13 * - ensure following expected behaviour in all cases... what is expected behaviour? remove+delete the old cat/tag/format?
14 * - cache cleaning (think wp_delete_term does most, if not all)
15 * - more UI cleanup (indent for child cats, what should convert to selectors look like?, ...)
16 * - re-introduce select all option (old button was ugly)
17 * - somehow use list tables? for: probably looks better, against: poss. bulky code
18 */
19
20if ( !defined('WP_LOAD_IMPORTERS') )
21        return;
22
23// Load Importer API
24require_once ABSPATH . 'wp-admin/includes/import.php';
25
26if ( !class_exists( 'WP_Importer' ) ) {
27        $class_wp_importer = ABSPATH . 'wp-admin/includes/class-wp-importer.php';
28        if ( file_exists( $class_wp_importer ) )
29                require_once $class_wp_importer;
30}
31
32/**
33 * Taxonomy Converter
34 *
35 * @package WordPress
36 * @subpackage Importer
37 */
38if ( class_exists( 'WP_Importer' ) ) {
39class WP_Taxonomy_Converter extends WP_Importer {
40        var $hybrids_ids = array();
41
42        function header( $current_tab ) {
43                if ( ! current_user_can('manage_categories') )
44                        wp_die( __( 'Cheatin&#8217; uh?', 'wpcat2tag-importer' ) );
45
46                global $wp_taxonomies; 
47                $tabs = array();
48                foreach ( $wp_taxonomies as $tax ) :
49                        if ($tax->public) :
50                                $tabs[$tax->name] = array( 'label' => $tax->label, 'url' => admin_url( 'admin.php?import=wpcat2tag&tab='.$tax->name ) );
51                        endif;
52                endforeach;
53
54                ?>
55                <div class="wrap">
56                <?php screen_icon(); ?>
57                <h2><?php _e( 'Categories, Tags, Formats, and Taxonomy Converter', 'wpcat2tag-importer' ); ?></h2>
58                <h3 class="nav-tab-wrapper">
59                <?php foreach ( $tabs as $tab => $info ) :
60                        $class = ($tab == $current_tab) ? ' nav-tab-active' : ''; ?>
61                        <a href="<?php echo $info['url']; ?>" class="nav-tab<?php echo $class; ?>"><?php echo esc_html( $info['label'] ); ?></a>
62                <?php endforeach; ?>
63                </h3>
64<?php
65        }
66
67        function footer() {
68                echo '</div>';
69        }
70
71        function populate_tax($taxonomy) {
72                $tags = get_terms( array($taxonomy), array('get' => 'all') );
73                foreach ( $tags as $tag ) {
74                        $this->all_tags[] = $tag;
75                        if ( term_exists( $tag->slug, 'category' ) && term_exists( $tag->slug, 'post_tag' ) )
76                                $this->hybrids_ids[] = $tag->term_id;
77                }
78        }
79
80        function do_tax_tab($tax) {
81                if ( isset($_POST['tax_to_convert']) ) {
82                        $this->convert_terms($_POST['tax_to_convert']);
83                        return;
84                }
85
86                $this->populate_tax($tax);
87                $alltaxes = get_terms( array($tax), array('get' => 'all') );
88                $tax_num = count( $alltaxes );
89                $tax = get_taxonomy($tax);
90               
91                if ( $tax_num > 0 ) {
92                        echo '<div class="narrow">';
93                        echo '<p>' . __( 'Hey there. Here you can selectively convert existing terms to other taxonomies (for example, categories to tags). To get started, check the terms you wish to be converted, then click the Convert button.', 'wpcat2tag-importer' ) . '</p>';
94                        if ($tax->hierarchical)
95                                echo '<p>' . __('Keep in mind that if you convert a category with child categories, the children become top-level orphans.', 'wpcat2tag-importer') . '</p>';
96                        echo '</div>';
97                        if ( term_exists( $tax->name, 'post_tag' ) && term_exists( $tax->name, 'category' ) )
98                                $this->hybrids_ids[] = $tax->term_id;
99                        $this->taxonomies_form($tax->name);
100                } else {
101                        echo '<p>'.__(sprintf('You have no %s to convert!', $tax->label), 'wpcat2tag-importer').'</p>';
102                }
103        }
104
105        function taxonomies_form($name) {
106                global $wp_taxonomies;
107                if (!isset($name))
108                        $name = 'category';
109                $taxonomy = get_taxonomy($name);
110                echo '<form name="taxlist" id="taxlist" action="admin.php?import=wpcat2tag&amp;tab='.$taxonomy->name.'" method="post">';
111                wp_nonce_field( 'import-cat2tag' );
112                echo '<input type="hidden" name="convert_from" value="'.$taxonomy->name.'" />';
113                echo '<ul>';
114
115                if ($taxonomy->hierarchical)
116                        $hier = _get_term_hierarchy( $taxonomy->name );
117                $allterms = get_terms( array($taxonomy->name), array('get' => 'all') );
118                foreach ( $allterms as $term ) {
119                        $term = sanitize_term( $term, $taxonomy->name, 'display' );
120
121                        if ( (int) $term->parent == 0 ) {
122                                echo '<li><label><input type="checkbox" name="tax_to_convert[]" value="' . intval($term->term_id) . '" /> ' . esc_html($term->name) . " ({$term->count})</label>";
123
124                                if ( in_array( intval($term->term_id),  $this->hybrids_ids ) )
125                                        echo ' <a href="#note"> * </a>';
126
127                                if ($taxonomy->hierarchical && isset($hier[$term->term_id]) )
128                                        $this->_category_children($term, $hier, $taxonomy->name);
129
130                                echo '</li>';
131                        }
132                }
133                echo '</ul>';
134
135                if ( ! empty($this->hybrids_ids) )
136                        echo '<p><a name="note"></a>' . __('* This category is also a tag. Converting it will add that tag to all posts that are currently in the category.', 'wpcat2tag-importer') . '</p>';
137                       
138                ?>
139                <p><?php _e( 'Convert categories to:', 'wpcat2tag-importer' ); ?><br />
140                        <label><input type="radio" name="convert_to" value="tags" checked="checked" /> <?php _e( 'Tags', 'wpcat2tag-importer' ); ?></label><br />
141                <?php
142
143                if ( current_theme_supports( 'post-formats' ) ) :
144                        $post_formats = get_theme_support( 'post-formats' );
145                        if ( is_array( $post_formats[0] ) ) : ?>
146                                <label><input type="radio" name="convert_to" value="post_format" /> <?php _e( 'Post Format', 'wpcat2tag-importer' ); ?></label>
147                                        <select name="post_format">
148                                        <?php foreach ( $post_formats[0] as $format ) : ?>
149                                                <option value="<?php echo esc_attr( $format ); ?>"><?php echo esc_html( get_post_format_string( $format ) ); ?></option>
150                                        <?php endforeach; ?>
151                                        </select><br />
152                                <?php 
153                        endif; 
154                endif; 
155               
156                foreach ( $wp_taxonomies as $tax ) :
157                        // exclude currently selected taxonomy, tags, and post formats
158                        if ( !in_array($tax->name, array('post_format', 'post_tag', $name)) && $tax->public ) : 
159                        $terms = get_terms( array($tax->name), array('get' => 'all') );
160                        ?>
161                                <label><input type="radio" name="convert_to" value="<?php echo esc_attr($tax->name); ?>" /> <?php echo esc_html($tax->label); ?></label><br />
162                        <?php                           
163                        endif;
164                endforeach;
165                ?>
166               
167                </p>
168                <p class="submit"><input type="submit" name="submit" class="button" value="<?php esc_attr_e( 'Convert Categories', 'wpcat2tag-importer' ); ?>" /></p>
169                </form><?php
170        }
171
172        function _category_children( $parent, $hier, $taxonomy ) {
173                echo '<ul>';
174
175                foreach ( $hier[$parent->term_id] as $child_id ) {
176                        $child =& get_term($child_id, $taxonomy);
177
178                        echo '<li><label><input type="checkbox" name="tax_to_convert[]" value="'. intval($child->term_id) .'" /> ' . esc_html($child->name) . " ({$child->count})</label>";
179
180                        if ( in_array( intval($child->term_id), $this->hybrids_ids ) )
181                                echo ' <a href="#note"> * </a>';
182
183                        if ( isset($hier[$child->term_id]) )
184                                $this->_category_children($child, $hier, $taxonomy);
185
186                        echo '</li>';
187                }
188
189                echo '</ul>';
190        }
191
192        function convert_terms() {
193                check_admin_referer( 'import-cat2tag' );
194                if (isset($_POST['convert_from'])) 
195                        $tax = get_taxonomy($_POST['convert_from']);
196                               
197                if ( ! is_array($_POST['tax_to_convert']) || !isset($_POST['convert_to']) || !isset($_POST['convert_from']) || !$tax ) {
198                        echo '<div class="narrow">';
199                        echo '<p>' . sprintf(__('Uh, oh. Something didn&#8217;t work. Please <a href="%s">try again</a>.', 'wpcat2tag-importer'), 'admin.php?import=wpcat2tag') . '</p>';
200                        echo '</div>';
201                        return;
202                }
203
204                if ( 'post_format' == $_POST['convert_to'] ) {
205                        $convert_to = 'post_format';
206                        $term_info = $this->_get_format_info( sanitize_key($_POST['post_format']) );
207                        if ( is_wp_error($term_info) ) {
208                                echo '<div class="narrow"><p>';
209                                echo $term_info->get_error_message() . ' ';
210                                printf( __( 'Please <a href="%s">try again</a>.', 'wpcat2tag-importer' ), 'admin.php?import=wpcat2tag&amp;tab='.$tax->name );
211                                echo '</p></div>';
212                                return;
213                        }
214                }
215                else {
216                        $convert_to = $_POST['convert_to'];
217                        echo '<ul>';
218                        foreach ( $_POST['tax_to_convert'] as $term_id ) {
219                                $term_id = (int) $term_id;
220                                $term = get_term( $term_id, $tax->name );
221                                if ( ! $term ) {
222                                        echo '<li>' . sprintf( __( 'Tag #%d doesn&#8217;t exist!', 'wpcat2tag-importer' ), $term_id ) . "</li>\n";
223                                } else {
224                                        echo '<li>' . sprintf( __( 'Converting tag <strong>%s</strong> ... ', 'wpcat2tag-importer' ), esc_html($term->name) );
225
226                                if ( ! $term_info = term_exists( $term->slug, $convert_to ) )
227                                        $term_info = wp_insert_term( $term->name, $convert_to, array( 'description' => $term->description ) );
228                       
229                                if ( is_wp_error($term_info) ) {
230                                        echo $term_info->get_error_message() . "</li>\n";
231                                        continue;
232                                }
233                               
234                                $default = get_option( 'default_category' );
235
236                                // if this is the default category then leave it in place and just add the new tag/format/whatever
237                                if ( 'category' == $tax->name && $default == $term->term_id ) {
238                                        $posts = get_objects_in_term( $term->term_id, 'category' );
239                                        foreach ( $posts as $post ) {
240                                                $values[] = $wpdb->prepare( "(%d, %d, 0)", $post, $term_info['term_taxonomy_id'] );
241                                                clean_post_cache( $post );
242                                        }
243       
244                                        $wpdb->query( "INSERT INTO {$wpdb->term_relationships} (object_id, term_taxonomy_id, term_order) VALUES " . join(',', $values) );
245                                        $wpdb->update( $wpdb->term_taxonomy, array( 'count' => $term->count ), array( 'term_id' => $term_info['term_id'], 'taxonomy' => $convert_to ) );
246
247                                // otherwise just convert it
248                                } else {
249                                        $this->_convert_term( array( 'term_id' => $term->term_id, 'taxonomy' => $tax->name, 'term_taxonomy_id' => $term->term_taxonomy_id ), $term_info['term_taxonomy_id'] );
250                                }
251                               
252                                echo __( 'Converted successfully.', 'wpcat2tag-importer' ) . "</li>\n";
253                                }
254                        }
255
256                        echo '</ul>';
257                }
258                echo '<p>' . sprintf( __( 'We&#8217;re all done here, but you can always <a href="%s">convert more</a>.', 'wpcat2tag-importer' ), admin_url( 'admin.php?import=wpcat2tag&amp;tab='.$tax->name ) ) . '</p>';
259        }
260
261        /**
262         * Convert all term relationships to a new term, delete the old term if possible.
263         *
264         * The old term will not be deleted if it's the default category or if it's a part
265         * of any other taxonomies.
266         *
267         * @param array $from term_id, taxonomy and term_taxonomy_id of the term+taxonomy pair converting from
268         * @param int $to_ttid The term_taxonomy_id of the term+taxonomy pair we are converting to
269         */
270        function _convert_term( $from, $to_ttid ) {
271                global $wpdb;
272
273                // transfer all the term relationships
274                $wpdb->update( $wpdb->term_relationships, array( 'term_taxonomy_id' => $to_ttid ), array( 'term_taxonomy_id' => $from['term_taxonomy_id'] ) );
275
276                // remove the old term
277                wp_delete_term( $from['term_id'], $from['taxonomy'] );
278        }
279
280        function _get_format_info( $format ) {
281                if ( current_theme_supports( 'post-formats' ) && ! empty( $format ) ) {
282                        $post_formats = get_theme_support( 'post-formats' );
283                        if ( is_array( $post_formats ) ) {
284                                $post_formats = $post_formats[0];
285                                if ( ! in_array( $format, $post_formats ) )
286                                        return new WP_Error( 'invalid_format', sprintf( __( 'Bad post format %s.', 'wpcat2tag-importer' ), esc_html($format) ) );
287                        }
288                } else {
289                        return new WP_Error( 'invalid_format', __( 'Either your theme does not support post formats or you supplied an invalid format.', 'wpcat2tag-importer' ) );
290                }
291
292                $format = 'post-format-' . $format;
293                if ( ! $term_info = term_exists( $format, 'post_format' ) )
294                        $term_info = wp_insert_term( $format, 'post_format' );
295
296                return $term_info;
297        }
298
299        function init() {
300                if ( ! current_user_can( 'manage_categories' ) )
301                        wp_die( __( 'Cheatin&#8217; uh?', 'wpcat2tag-importer' ) );
302
303                $tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'category';
304                $this->header( $tab );
305
306                $this->do_tax_tab( $tab );
307
308                $this->footer();
309        }
310
311        function WP_Taxonomy_Converter() { /* Do nothing. */ }
312}
313
314$wp_cat2tag_importer = new WP_Taxonomy_Converter();
315register_importer('wpcat2tag', __('Categories, Tags, Formats, and Taxonomy Converter', 'wpcat2tag-importer'), __('Convert existing categories or tags to other taxonomies, selectively.', 'wpcat2tag-importer'), array(&$wp_cat2tag_importer, 'init'));
316
317} // class_exists( 'WP_Importer' )
318
319function wpcat2tag_importer_init() {
320    load_plugin_textdomain( 'wpcat2tag-importer', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
321}
322add_action( 'init', 'wpcat2tag_importer_init' );
323?>