PluginProbe ʕ •ᴥ•ʔ
Permalink Manager Lite / 0.2
Permalink Manager Lite v0.2
2.5.3.4 2.2.18 2.2.19.2 2.2.19.3 2.2.19.3.1 2.2.2 2.2.20 2.2.20.1 2.2.20.3 2.2.4 2.2.5 2.2.6 2.2.7.2 2.2.7.3 2.2.7.5 2.2.7.6 2.2.8.4 2.2.8.5 2.2.8.6 2.2.8.7 2.2.8.9 2.2.9.1 2.2.9.2 2.2.9.2.1 2.2.9.3 2.2.9.4 2.2.9.6 2.2.9.7 2.2.9.9 2.3.0 2.3.1.1 2.4.0 2.4.1 2.4.1.2 2.4.1.3 2.4.1.4 2.4.1.5 2.4.1.6 2.4.2 2.4.2.1 2.4.3 2.4.3.1 2.4.3.2 2.4.3.3 2.4.3.4 2.4.4 2.4.4.1 2.4.4.2 2.4.4.3 2.5.0 2.5.1 2.5.1.1 2.5.1.2 2.5.1.3 2.5.1.4 2.5.2 2.5.2.1 2.5.2.2 2.5.2.3 2.5.2.4 2.5.3 2.5.3.1 2.5.3.2 2.5.3.3 trunk 0.2 0.3 0.3.1 0.3.2 0.3.3 0.3.4 0.4 0.4.1 0.4.2 0.4.3 0.4.4 0.4.6 0.4.7 0.4.8 0.4.9 0.5.3 0.5.4 1.0.0 1.0.1 1.0.4 1.1.0 1.1.1 1.1.2 1.11.6.3 2.0.0 2.0.3 2.0.4 2.0.4.3 2.0.5.1 2.0.5.2 2.0.5.3 2.0.5.3.1 2.0.5.4 2.0.5.4a 2.0.5.5 2.0.5.6 2.0.5.6.1 2.0.5.7 2.0.5.9a 2.0.6.2.1 2.0.6.2a 2.0.6.3 2.1.0 2.1.1 2.1.2.4 2.2.0 2.2.1.1 2.2.1.2 2.2.11 2.2.12 2.2.13.1 2.2.14 2.2.15.1 2.2.16 2.2.17
permalink-manager / permalink-manager.php
permalink-manager Last commit date
css 10 years ago inc 10 years ago js 10 years ago languages 10 years ago LICENSE.txt 10 years ago README.md 10 years ago README.txt 10 years ago permalink-manager.php 10 years ago
permalink-manager.php
484 lines
1 <?php
2
3 /**
4 * Plugin Name: Permalink Manager
5 * Plugin URI: http://maciejbis.net/
6 * Description: A simple tool that allows to mass update of slugs that are used to build permalinks for Posts, Pages and Custom Post Types.
7 * Version: 0.2.0
8 * Author: Maciej Bis
9 * Author URI: http://maciejbis.net/
10 * License: GPL-2.0+
11 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
12 * Text Domain: permalink-manager
13 * Domain Path: /languages
14 */
15
16 // If this file is called directly, abort.
17 if ( ! defined( 'WPINC' ) ) {
18 die;
19 }
20
21 // Define the directories used to load plugin files.
22 define( 'PERMALINK_MANAGER_PLUGIN_NAME', 'permalink-manager' );
23 define( 'PERMALINK_MANAGER_VERSION', '0.2.0' );
24 define( 'PERMALINK_MANAGER_DIR', untrailingslashit( dirname( __FILE__ ) ) );
25 define( 'PERMALINK_MANAGER_URL', untrailingslashit( plugins_url( '', __FILE__ ) ) );
26 define( 'PERMALINK_MANAGER_WEBSITE', 'http://maciejbis.net' );
27 define( 'PERMALINK_MANAGER_MENU_PAGE', 'tools_page_permalink-manager' );
28 define( 'PERMALINK_MANAGER_OPTIONS_PAGE', PERMALINK_MANAGER_PLUGIN_NAME . '.php' );
29
30 class Permalink_Manager_Class {
31
32 protected $permalink_manager, $admin_page, $permalink_manager_options, $permalink_manager_options_page;
33
34 public function __construct() {
35
36 $this->permalink_manager_options = get_option('permalink-manager');
37
38 add_action( 'plugins_loaded', array($this, 'localize_me') );
39 add_action( 'admin_init', array($this, 'process_forms') );
40 add_action( 'admin_menu', array($this, 'add_menu_page') );
41 add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), array($this, 'plugins_page_links') );
42
43 }
44
45 /**
46 * Localize this plugin
47 */
48 function localize_me() {
49 load_plugin_textdomain( 'permalink-manager', false, PERMALINK_MANAGER_DIR );
50 }
51
52 /**
53 * Add menu page and load CSS & JS.
54 */
55 function add_menu_page() {
56 add_management_page( __('Permalink Manager', 'permalink-manager'), __('Permalink Manager', 'permalink-manager'), 'manage_options', PERMALINK_MANAGER_OPTIONS_PAGE, array($this, 'list_slugs_admin_page') );
57
58 // Make sure thata the CSS and JS files are loaded only on plugin admin page.
59 add_action( 'admin_print_scripts-' . PERMALINK_MANAGER_MENU_PAGE, array($this, 'enqueue_styles' ) );
60 add_action( 'admin_print_scripts-' . PERMALINK_MANAGER_MENU_PAGE, array($this, 'enqueue_scripts' ) );
61 }
62
63 /**
64 * Display the table with slugs.
65 */
66 function permalinks_table_html() {
67 global $wpdb;
68
69 $Permalink_Manager_Table = new Permalink_Manager_Table();
70 $Permalink_Manager_Table->set_screen_option_fields($this->fields_arrays('screen_options'));
71 $Permalink_Manager_Table->prepare_items($wpdb->posts);
72
73 ?>
74
75 <form id="permalinks-table" method="post">
76 <input type="hidden" name="page" value="<?php echo $_POST['page']; ?>" />
77 <?php echo $Permalink_Manager_Table->display(); ?>
78 </form>
79 <?php
80 }
81
82 /**
83 * Mass replace options page.
84 */
85 function find_and_replace_html() {
86 $button = get_submit_button( __( 'Find & Replace', 'permalink-manager' ), 'primary', 'find-replace-button', false );
87
88 $return = "<form id=\"permalinks-table-find-replace\" method=\"post\">";
89 $return .= "<table class=\"form-table\">";
90
91 foreach($this->fields_arrays('find_replace') as $field_name => $field_args) {
92 $return .= Permalink_Manager_Helper_Functions::generate_option_field($field_name, $field_args, 'find-replace');
93 }
94
95 $return .= "</table>{$button}";
96 $return .= "</form>";
97
98 echo $return;
99 }
100
101 /**
102 * Reset slugs page.
103 */
104 function regenerate_slugs_html() {
105 $button = get_submit_button( __( 'Regenerate', 'permalink-manager' ), 'primary', 'regenerate-button', false );
106
107 $return = "<form id=\"permalinks-table-regenerate\" method=\"post\">";
108 $return .= "<table class=\"form-table\">";
109
110 foreach($this->fields_arrays('regenerate') as $field_name => $field_args) {
111 $return .= Permalink_Manager_Helper_Functions::generate_option_field($field_name, $field_args, 'regenerate');
112 }
113
114 $return .= "</table>{$button}";
115 $return .= "</form>";
116
117 echo $return;
118 }
119
120 /**
121 * Display the plugin dashboard.
122 */
123 function list_slugs_admin_page() {
124 global $wpdb;
125
126 // Check which tab is active now.
127 $active_tab = ( isset( $_GET[ 'tab' ] ) ) ? $_GET[ 'tab' ] : 'permalinks';
128
129 // Tabs array with assigned functions used to display HTML content.
130 $tabs = array(
131 'permalinks' => array(
132 'name' => __('Permalinks', 'permalink-manager'),
133 'function' => 'permalinks_table_html',
134 'description' => __('You can disable/enable selected post types from the table below using <strong>"Screen Options"</strong> (click on the upper-right button to show it) section above.', 'permalink-manager')
135 ),
136 'find_and_replace' => array(
137 'name' => __('Find and replace', 'permalink-manager'),
138 'function' => 'find_and_replace_html',
139 'warning' => (__('<strong>You are doing it at your own risk!</strong>', 'permalink-manager') . '<br />' . __('A backup of MySQL database before using this tool is highly recommended. The search & replace operation might be not revertible!', 'permalink-manager'))
140 ),
141 'regenerate_slugs' => array(
142 'name' => __('Regenerate slugs', 'permalink-manager'),
143 'function' => 'regenerate_slugs_html',
144 'warning' => (__('<strong>You are doing it at your own risk!</strong>', 'permalink-manager') . '<br />' . __('A backup of MySQL database before using this tool is highly recommended. The regenerate process of slugs might be not revertible!', 'permalink-manager'))
145 ),
146 );
147
148 ?>
149 <div id="permalinks-table-wrap" class="wrap">
150
151 <?php
152 // Display alerts and another content if needed
153 echo apply_filters('permalink-manager-before-tabs','');
154 ?>
155
156 <div id="icon-themes" class="icon32"></div>
157 <h2 id="plugin-name-heading"><?php _e('Permalink Manager', 'permalink-manager'); ?> <a href="<?php echo PERMALINK_MANAGER_WEBSITE; ?>" target="_blank"><?php _e('by Maciej Bis', 'permalink-manager'); ?></a></h2>
158
159 <h2 id="permalink-manager-tabs-nav" class="nav-tab-wrapper">
160 <?php
161 foreach($tabs as $tab_id => $tab_properties) {
162 $active_class = ($active_tab === $tab_id) ? 'nav-tab-active nav-tab' : 'nav-tab';
163 echo '<a data-tab="' . $tab_id . '" href="' . admin_url('admin.php?page=' . PERMALINK_MANAGER_PLUGIN_NAME . '.php&tab=' . $tab_id) . '" class="' . $active_class . '">' . $tab_properties['name'] . '</a>';
164 } ?>
165 </h2>
166
167 <div id="permalink-manager-tabs">
168 <?php
169 foreach($tabs as $tab_id => $tab_properties) {
170 $active_show = ($active_tab === $tab_id) ? 'show' : '';
171
172 echo '<div data-tab="' . $tab_id . '" id="' . $tab_id . '" class="' . $active_show . '">';
173 echo (isset($tab_properties['description'])) ? "<div class=\"info alert\"><p>{$tab_properties['description']}</p></div>" : "";
174 echo (isset($tab_properties['warning'])) ? "<div class=\"warning alert\"><p>{$tab_properties['warning']}</p></div>" : "";
175 $this->$tab_properties['function']();
176 echo '</div>';
177 } ?>
178 </div>
179
180 <?php
181 // Display alerts and another content if needed
182 echo apply_filters('permalink-manager-after-tabs','');
183 ?>
184
185 </div>
186 <?php
187 }
188
189 /**
190 * Register the stylesheets for the Dashboard.
191 */
192 function enqueue_styles() {
193 wp_enqueue_style( PERMALINK_MANAGER_PLUGIN_NAME, PERMALINK_MANAGER_URL . '/css/permalink-manager-admin.css', array(), PERMALINK_MANAGER_VERSION, 'all' );
194 }
195
196 /**
197 * Register the JavaScript for the dashboard.
198 */
199 function enqueue_scripts() {
200 wp_enqueue_script( PERMALINK_MANAGER_PLUGIN_NAME, PERMALINK_MANAGER_URL . '/js/permalink-manager-admin.js', array( 'jquery' ), PERMALINK_MANAGER_VERSION, false );
201 }
202
203 /**
204 * Additional links on "Plugins" page
205 */
206 function plugins_page_links( $links ) {
207 $links[] = '<a href="' . esc_url( get_admin_url(null, "tools.php?page=" . PERMALINK_MANAGER_OPTIONS_PAGE) ) .'">' . __( 'Go To Permalink Manager', 'permalink-manager' ) . '</a>';
208 return $links;
209 }
210
211 /**
212 * Fields for "Screen Options"
213 */
214 function fields_arrays($array) {
215
216 // All registered post types array
217 $all_post_types_array = Permalink_Manager_Helper_Functions::get_post_types_array();
218 $all_post_statuses_array = get_post_statuses();
219
220 // Fields for "Screen Options"
221 $screen_options = array(
222 'post_types' => array(
223 'label' => __( 'Post Types', 'permalink-manager' ),
224 'type' => 'checkbox',
225 'choices' => array_merge(array('all' => '<strong>' . __('All Post Types', 'permalink-manager') . '</strong>'), $all_post_types_array),
226 'default' => array('post', 'page')
227 ),
228 'post_statuses' => array(
229 'label' => __( 'Post Statuses', 'permalink-manager' ),
230 'type' => 'checkbox',
231 'choices' => array_merge(array('all' => '<strong>' . __('All Post Statuses', 'permalink-manager') . '</strong>'), $all_post_statuses_array),
232 'default' => array('publish')
233 ),
234 'per_page' => array(
235 'label' => __( 'Per page', 'permalink-manager' ),
236 'type' => 'number',
237 'default' => 10
238 )
239 );
240
241 // Fields for "Find and replace"
242 $find_replace = array(
243 'old_string' => array(
244 'label' => __( 'Find ...', 'permalink-manager' ),
245 'type' => 'text',
246 ),
247 'new_string' => array(
248 'label' => __( 'Replace with ...', 'permalink-manager' ),
249 'type' => 'text',
250 ),
251 'post_types' => array(
252 'label' => __( 'Post Types that should be affected', 'permalink-manager' ),
253 'type' => 'checkbox',
254 'choices' => array_merge(array('all' => '<strong>' . __('All Post Types', 'permalink-manager') . '</strong>'), $all_post_types_array),
255 'default' => array('post', 'page')
256 ),
257 'post_statuses' => array(
258 'label' => __( 'Post Statuses that should be affected', 'permalink-manager' ),
259 'type' => 'checkbox',
260 'choices' => array_merge(array('all' => '<strong>' . __('All Post Statuses', 'permalink-manager') . '</strong>'), $all_post_statuses_array),
261 'default' => array('publish')
262 )
263 );
264
265 // Fields for "Regenerate slugs"
266 $regenerate = array(
267 'post_types' => array(
268 'label' => __( 'Post Types that should be affected', 'permalink-manager' ),
269 'type' => 'checkbox',
270 'choices' => array_merge(array('all' => '<strong>' . __('All Post Types', 'permalink-manager') . '</strong>'), $all_post_types_array),
271 'default' => array('post', 'page')
272 ),
273 'post_statuses' => array(
274 'label' => __( 'Post Statuses that should be affected', 'permalink-manager' ),
275 'type' => 'checkbox',
276 'choices' => array_merge(array('all' => '<strong>' . __('All Post Statuses', 'permalink-manager') . '</strong>'), $all_post_statuses_array),
277 'default' => array('publish')
278 )
279 );
280
281 return isset($array) ? ${$array} : array();
282 }
283
284 /**
285 * Check if the provided slug is unique and then update it with SQL query.
286 */
287 function update_slug_by_id($slug, $id) {
288 global $wpdb;
289
290 // Update slug and make it unique
291 $slug = (empty($slug)) ? sanitize_title(get_the_title($id)) : $slug;
292 $new_slug = wp_unique_post_slug($slug, $id, get_post_status($id), get_post_type($id), null);
293 $wpdb->query("UPDATE $wpdb->posts SET post_name = '$new_slug' WHERE ID = '$id'");
294
295 return $new_slug;
296 }
297
298 /**
299 * Bulk actions functions
300 */
301 function process_forms() {
302 global $wpdb;
303 $updated_slugs_count = 0;
304 $updated_array = array();
305 $alert_type = $alert_content = $errors = $main_content = '';
306
307 if (isset($_POST['update_all_slugs'])) {
308
309 $slugs = isset($_POST['slug']) ? $_POST['slug'] : array();
310
311 // Double check if the slugs and ids are stored in arrays
312 if (!is_array($slugs)) $slugs = explode(',', $slugs);
313
314 if (!empty($slugs)) {
315 foreach($slugs as $id => $new_slug) {
316 $this_post = get_post($id);
317
318 // Check if slug was changed
319 if($this_post->post_name != $new_slug) {
320 // Update slugs
321 $this->update_slug_by_id($new_slug, $id);
322
323 $updated_array[] = array('post_title' => get_the_title($id), 'old_slug' => $this_post->post_name, 'new_slug' => $new_slug);
324 $updated_slugs_count++;
325 }
326
327 // Reset slug
328 $slug = '';
329 }
330 }
331
332 } else if (isset($_POST['find-replace-button'])) {
333
334 $var['old_string'] = esc_sql($_POST['permalink-manager']['find-replace']['old_string']);
335 $var['new_string'] = esc_sql($_POST['permalink-manager']['find-replace']['new_string']);
336 $post_types_array = ($_POST['permalink-manager']['find-replace']['post_types']);
337 $post_statuses_array = ($_POST['permalink-manager']['find-replace']['post_statuses']);
338 $var['post_types'] = implode("', '", $post_types_array);
339 $var['post_statuses'] = implode("', '", $post_statuses_array);
340
341 // Check if any of variables is not empty
342 $find_replace_fields = $this->fields_arrays('find_replace');
343 foreach($var as $key => $val) {
344 if(empty($val)) $errors .= '<p>' . sprintf( __( '<strong>"%1s"</strong> field is empty!', 'permalink-manager' ), $find_replace_fields[$key]['label'] ) . '</p>';
345 }
346
347 // Save the rows before they are updated to an array
348 $posts_to_update = $wpdb->get_results("SELECT post_title, post_name, ID FROM {$wpdb->posts} WHERE post_status IN ('{$var['post_statuses']}') AND post_name LIKE '%{$var['old_string']}%' AND post_type IN ('{$var['post_types']}')", ARRAY_A);
349
350 // Now if the array is not empty use IDs from each subarray as a key
351 if($posts_to_update && empty($errors)) {
352 foreach ($posts_to_update as $row) {
353 // Get new slug
354 $old_slug = $row['post_name'];
355 $new_slug = str_replace($var['old_string'], $var['new_string'], $old_slug);
356
357 // Update slugs
358 $this->update_slug_by_id($new_slug, $row['ID']);
359
360 $updated_array[] = array('post_title' => $row['post_title'], 'old_slug' => $old_slug, 'new_slug' => $new_slug);
361 $updated_slugs_count++;
362
363 // Reset slug
364 $slug = '';
365 }
366 } else {
367 $alert_type = 'error';
368 $alert_content = $errors;
369 }
370
371
372 } else if (isset($_POST['regenerate-button'])) {
373
374 // Setup needed variables
375 $post_types_array = ($_POST['permalink-manager']['regenerate']['post_types']);
376 $post_statuses_array = ($_POST['permalink-manager']['regenerate']['post_statuses']);
377
378 // Reset query
379 $reset_query = new WP_Query( array( 'post_type' => $post_types_array, 'post_status' => $post_statuses_array, 'posts_per_page' => -1 ) );
380
381 // The Loop
382 if ( $reset_query->have_posts() ) {
383 while ( $reset_query->have_posts() ) {
384 $reset_query->the_post();
385 $this_post = get_post(get_the_ID());
386
387 $correct_slug = sanitize_title(get_the_title());
388 $old_slug = $this_post->post_name;
389 $new_slug = wp_unique_post_slug($correct_slug, get_the_ID(), get_post_status(get_the_ID()), get_post_type(get_the_ID()), null);
390
391 if($old_slug != $new_slug) {
392 $updated_slugs_count++;
393
394 $this->update_slug_by_id($new_slug, get_the_ID());
395 $updated_array[] = array('post_title' => get_the_title(), 'old_slug' => $old_slug, 'new_slug' => $new_slug);
396 }
397 }
398 }
399
400 // Restore original Post Data
401 wp_reset_postdata();
402
403 }
404
405 /**
406 * Display results
407 */
408 if((isset($_POST['permalink-manager']) || isset($_POST['update_all_slugs'])) && !(isset($_POST['screen-options-apply']))) {
409 // Display errors or success message
410 add_filter('permalink-manager-before-tabs', function( $arg ) use ( $updated_slugs_count, $alert_content, $alert_type ) {
411
412 // Check how many rows/slugs were affected
413 if($updated_slugs_count > 0) {
414 $alert_type = 'updated';
415 $alert_content = sprintf( _n( '<strong>%d</strong> slug were updated!', '<strong>%d</strong> slugs were updated!', $updated_slugs_count, 'permalink-manager' ), $updated_slugs_count ) . ' ';
416 $alert_content .= sprintf( __( '<a href="%s">Click here</a> to go to the list of updated slugs', 'permalink-manager' ), '#updated-list');
417 } else {
418 $alert_type = 'error';
419 $alert_content = ($alert_content) ? $alert_content : __( '<strong>No slugs</strong> were updated!', 'permalink-manager' );
420 }
421
422 return Permalink_Manager_Helper_Functions::display_alert($alert_content, $alert_type);
423
424 });
425
426 // Display summary after update
427 // Display only if there are any slugs updated
428 if ( $updated_slugs_count > 0 && $updated_array ) {
429 add_filter('permalink-manager-after-tabs', function( $arg ) use ( $alert_content, $alert_type, $errors, $updated_array, $main_content ) {
430
431 $header_footer = '<tr>';
432 $header_footer .= '<th class="column-primary">' . __('Title', 'permalink-manager') . '</th>';
433 $header_footer .= '<th>' . __('Old slug', 'permalink-manager') . '</th>';
434 $header_footer .= '<th>' . __('New slug', 'permalink-manager') . '</th>';
435 $header_footer .= '</tr>';
436
437 $updated_slugs_count = 0;
438 foreach($updated_array as $row) {
439 // Odd/even class
440 $updated_slugs_count++;
441 $alternate_class = ($updated_slugs_count % 2 == 1) ? ' class="alternate"' : '';
442
443 $main_content .= "<tr{$alternate_class}>";
444 $main_content .= '<td class="row-title column-primary" data-colname="' . __('Title', 'permalink-manager') . '">' . $row['post_title'] . '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __('Show more details', 'permalink-manager') . '</span></button></td>';
445 $main_content .= '<td data-colname="' . __('Old slug', 'permalink-manager') . '">' . $row['old_slug'] . '</td>';
446 $main_content .= '<td data-colname="' . __('New slug', 'permalink-manager') . '">' . $row['new_slug'] . '</td>';
447 $main_content .= '</tr>';
448 }
449
450 // Merge header, footer and content
451 $output = '<h3 id="updated-list">' . __('List of updated posts', 'permalink-manager') . '</h3>';
452 $output .= '<table class="widefat wp-list-table">';
453 $output .= "<thead>{$header_footer}</thead><tbody>{$main_content}</tbody><tfoot>{$header_footer}</tfoot>";
454 $output .= '</table>';
455
456 return $output ;
457
458 });
459 }
460 }
461 }
462 }
463
464 /**
465 * Begins execution of the plugin.
466 */
467 function run_permalink_manager() {
468
469 // Load plugin files.
470 if( is_admin() ) {
471
472 require_once PERMALINK_MANAGER_DIR . '/inc/permalink-manager-wp-table.php';
473 require_once PERMALINK_MANAGER_DIR . '/inc/permalink-manager-screen-options.php';
474 require_once PERMALINK_MANAGER_DIR . '/inc/permalink-manager-helper-functions.php';
475
476 $Permalink_Manager_Class = new Permalink_Manager_Class();
477 $Permalink_Manager_Screen_Options = new Permalink_Manager_Screen_Options();
478
479 }
480
481 }
482
483 run_permalink_manager();
484