PluginProbe ʕ •ᴥ•ʔ
Permalink Manager Lite / 0.4.7
Permalink Manager Lite v0.4.7
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 9 years ago inc 9 years ago js 9 years ago languages 9 years ago LICENSE.txt 9 years ago README.txt 9 years ago permalink-manager.php 9 years ago
permalink-manager.php
757 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.4.7
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.4.7' );
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_page, $permalink_manager_options;
33
34 public function __construct() {
35
36 $this->permalink_manager_options = get_option('permalink-manager');
37 $this->permalink_manager_uris = get_option('permalink-manager-uris');
38 $this->permalink_manager_permastructs = get_option('permalink-manager-permastructs');
39
40 if( is_admin() ) {
41 add_action( 'plugins_loaded', array($this, 'localize_me') );
42 add_action( 'init', array($this, 'upgrade_plugin'), 999 );
43 add_action( 'init', array($this, 'debug_functions'), 999999999999 );
44 add_action( 'wp_loaded', array($this, 'bulk_actions'), 1 );
45 add_action( 'admin_menu', array($this, 'add_menu_page') );
46 add_action( 'save_post', array($this, 'update_single_uri'), 10, 3 );
47 add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), array($this, 'plugins_page_links') );
48 add_filter( 'get_sample_permalink_html', array($this, 'edit_uri_box'), 10, 4 );
49 }
50
51 add_action( 'wp_loaded', array($this, 'permalink_filters'), 999);
52 add_action( 'template_redirect', array($this, 'redirect_to_new_uri'), 999);
53
54 }
55
56 function permalink_filters() {
57 // Public functions
58 add_filter( 'request', array($this, 'detect_post') );
59 add_filter( '_get_page_link', array($this, 'custom_permalinks'), 999, 2);
60 add_filter( 'page_link', array($this, 'custom_permalinks'), 999, 2);
61 add_filter( 'post_link', array($this, 'custom_permalinks'), 999, 2);
62 add_filter( 'post_type_link', array($this, 'custom_permalinks'), 999, 2);
63 }
64
65 /**
66 * Localize this plugin
67 */
68 function localize_me() {
69 load_plugin_textdomain( 'permalink-manager', false, PERMALINK_MANAGER_DIR );
70 }
71
72 /**
73 * Add menu page and load CSS & JS.
74 */
75 function add_menu_page() {
76 add_management_page( __('Permalink Manager', 'permalink-manager'), __('Permalink Manager', 'permalink-manager'), 'manage_options', PERMALINK_MANAGER_OPTIONS_PAGE, array($this, 'list_slugs_admin_page') );
77
78 // Make sure thata the CSS and JS files are loaded only on plugin admin page.
79 add_action( 'admin_print_scripts-' . PERMALINK_MANAGER_MENU_PAGE, array($this, 'enqueue_styles' ) );
80 add_action( 'admin_print_scripts-' . PERMALINK_MANAGER_MENU_PAGE, array($this, 'enqueue_scripts' ) );
81 }
82
83 /**
84 * Display the table with slugs.
85 */
86 function slug_editor_html() {
87 global $wpdb;
88
89 $Permalink_Manager_Editor = new Permalink_Manager_Editor();
90 $Permalink_Manager_Editor->set_screen_option_fields($this->fields_arrays('screen_options'));
91 $Permalink_Manager_Editor->prepare_items($wpdb->posts);
92
93 ?>
94
95 <form id="permalinks-table" method="post">
96 <input type="hidden" name="tab" value="slug_editor" />
97 <?php echo $Permalink_Manager_Editor->display(); ?>
98 </form>
99 <?php
100 }
101
102 /**
103 * Mass replace options page.
104 */
105 function find_and_replace_html() {
106 $button = get_submit_button( __( 'Find & Replace Slugs', 'permalink-manager' ), 'primary', 'find-replace-button', false );
107
108 $return = "<form id=\"permalinks-table-find-replace\" method=\"post\">";
109 $return .= "<input type=\"hidden\" name=\"tab\" value=\"find_and_replace\" />";
110 $return .= "<table class=\"form-table\">";
111
112 foreach($this->fields_arrays('find_and_replace') as $field_name => $field_args) {
113 $return .= Permalink_Manager_Helper_Functions::generate_option_field($field_name, $field_args, 'find-replace');
114 }
115
116 $return .= "</table>{$button}";
117 $return .= "</form>";
118
119 echo $return;
120 }
121
122 /**
123 * Reset slugs page.
124 */
125 function regenerate_slugs_html() {
126 $button = get_submit_button( __( 'Regenerate', 'permalink-manager' ), 'primary', 'regenerate-button', false );
127
128 $return = "<form id=\"permalinks-table-regenerate\" method=\"post\">";
129 $return .= "<input type=\"hidden\" name=\"tab\" value=\"regenerate_slugs\" />";
130 $return .= "<table class=\"form-table\">";
131
132 foreach($this->fields_arrays('regenerate_slugs') as $field_name => $field_args) {
133 $return .= Permalink_Manager_Helper_Functions::generate_option_field($field_name, $field_args, 'regenerate_slugs');
134 }
135
136 $return .= "</table>{$button}";
137 $return .= "</form>";
138
139 echo $return;
140 }
141
142 /**
143 * Permalink Base Editor
144 */
145 function base_editor_html() {
146 global $wpdb, $wp_rewrite;
147
148 $Permalink_Manager_Base_Editor = new Permalink_Manager_Base_Editor();
149 $Permalink_Manager_Base_Editor->set_screen_option_fields($this->fields_arrays('screen_options'));
150 $Permalink_Manager_Base_Editor->prepare_items($wpdb->posts);
151 ?>
152
153 <form id="permalinks-base-table" method="post">
154 <input type="hidden" name="tab" value="base_editor" />
155 <?php echo $Permalink_Manager_Base_Editor->display(); ?>
156 </form>
157 <?php
158 }
159
160 /**
161 * Display the plugin dashboard.
162 */
163 function list_slugs_admin_page() {
164 global $wpdb;
165
166 // Check which tab is active now.
167 if(isset($_POST['tab'])) {
168 $active_tab = $_POST['tab'];
169 } else if(isset($_GET['tab'])) {
170 $active_tab = $_GET['tab'];
171 } else {
172 $active_tab = 'slug_editor';
173 }
174
175 // Tabs array with assigned functions used to display HTML content.
176 $tabs = array(
177 'slug_editor' => array(
178 'name' => __('Permalink editor', 'permalink-manager'),
179 'function' => 'slug_editor_html',
180 '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'),
181 ),
182 'find_and_replace' => array(
183 'name' => __('Find and replace', 'permalink-manager'),
184 'function' => 'find_and_replace_html'
185 ),
186 'regenerate_slugs' => array(
187 'name' => __('Regenerate/Reset', 'permalink-manager'),
188 'function' => 'regenerate_slugs_html'
189 ),
190 'base_editor' => array(
191 'name' => __('Base editor', 'permalink-manager'),
192 'function' => 'base_editor_html',
193 'warning' => array(
194 sprintf(__('<strong>This is an experimental feature!</strong> Please report all the bugs & issues <a href="%s">here</a>.', 'permalink-manager'), 'https://wordpress.org/support/plugin/permalink-manager'),
195 __('Each Custom Post Type should have their own, unique front (eg. <em>products</em> for Products)', 'permalink-manager'),
196 __('Please note that the following settings will be applied only to new posts.<br />If you want to apply them to exisiting posts, you will need to regenerate the URIs in <strong>"Regnerate/Reset"</strong> section (with <strong>"Slugs & bases"</strong> option selected).', 'permalink-manager'),
197 ),
198 'description' => (sprintf( __('All the <a href="%s" target="_blank">Structure Tags</a> allowed are listed below. Please note that some of them can be used only for particular Post Types.', 'permalink-manager'), "https://codex.wordpress.org/Using_Permalinks#Structure_Tags") . "<br />" . Permalink_Manager_Helper_Functions::get_all_structure_tags())
199 ),
200 );
201
202 ?>
203 <div id="permalinks-table-wrap" class="wrap">
204
205 <?php
206 // Display alerts and another content if needed
207 echo apply_filters('permalink-manager-before-tabs','');
208 ?>
209
210 <div id="icon-themes" class="icon32"></div>
211 <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>
212
213 <h2 id="permalink-manager-tabs-nav" class="nav-tab-wrapper">
214 <?php
215 foreach($tabs as $tab_id => $tab_properties) {
216 $active_class = ($active_tab === $tab_id) ? 'nav-tab-active nav-tab' : 'nav-tab';
217 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>';
218 } ?>
219 </h2>
220
221 <div id="permalink-manager-tabs">
222 <?php
223 foreach($tabs as $tab_id => $tab_properties) {
224 $active_show = ($active_tab === $tab_id) ? 'show' : '';
225
226 // Prepare warning & description texts
227 $warning = (isset($tab_properties['warning'])) ? $tab_properties['warning'] : '';
228 $description = (isset($tab_properties['description'])) ? $tab_properties['description'] : '';
229
230 if(is_array($warning)) {
231 $warning = "<ol>"; // Overwrite the variable
232 foreach($tab_properties['warning'] as $point) { $warning .= "<li>{$point}</li>"; }
233 $warning .= "</ol>";
234 }
235
236 if(is_array($description)) {
237 $description = "<ol>"; // Overwrite the variable
238 foreach($tab_properties['description'] as $point) { $description .= "<li>{$point}</li>"; }
239 $description .= "</ol>";
240 }
241
242 echo '<div data-tab="' . $tab_id . '" id="' . $tab_id . '" class="' . $active_show . '">';
243 echo ($warning) ? "<div class=\"warning alert\">" . wpautop($warning) . "</div>" : "";
244 echo (isset($tab_properties['description'])) ? "<div class=\"info alert\">" . wpautop($description) . "</div>" : "";
245 $function_name = $tab_properties['function'];
246 $this->$function_name();
247 echo '</div>';
248 } ?>
249 </div>
250
251 <?php
252 // Display alerts and another content if needed
253 echo apply_filters('permalink-manager-after-tabs','');
254 ?>
255
256 </div>
257 <?php
258 }
259
260 /**
261 * Register the stylesheets for the Dashboard.
262 */
263 function enqueue_styles() {
264 wp_enqueue_style( PERMALINK_MANAGER_PLUGIN_NAME, PERMALINK_MANAGER_URL . '/css/permalink-manager-admin.css', array(), PERMALINK_MANAGER_VERSION, 'all' );
265 }
266
267 /**
268 * Register the JavaScript for the dashboard.
269 */
270 function enqueue_scripts() {
271 wp_enqueue_script( PERMALINK_MANAGER_PLUGIN_NAME, PERMALINK_MANAGER_URL . '/js/permalink-manager-admin.js', array( 'jquery' ), PERMALINK_MANAGER_VERSION, false );
272 }
273
274 /**
275 * Additional links on "Plugins" page
276 */
277 function plugins_page_links( $links ) {
278 $links[] = '<a href="' . esc_url( get_admin_url(null, "tools.php?page=" . PERMALINK_MANAGER_OPTIONS_PAGE) ) .'">' . __( 'Go To Permalink Manager', 'permalink-manager' ) . '</a>';
279 return $links;
280 }
281
282 /**
283 * Fields for "Screen Options"
284 */
285 function fields_arrays($array) {
286
287 // All registered post types array
288 $all_post_statuses_array = get_post_statuses();
289 $all_post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
290
291 // Fields for "Screen Options"
292 $screen_options = array(
293 'post_types' => array(
294 'label' => __( 'Post Types', 'permalink-manager' ),
295 'type' => 'checkbox',
296 'choices' => array_merge(array('all' => '<strong>' . __('All Post Types', 'permalink-manager') . '</strong>'), $all_post_types),
297 'default' => array('post', 'page')
298 ),
299 'post_statuses' => array(
300 'label' => __( 'Post Statuses', 'permalink-manager' ),
301 'type' => 'checkbox',
302 'choices' => array_merge(array('all' => '<strong>' . __('All Post Statuses', 'permalink-manager') . '</strong>'), $all_post_statuses_array),
303 'default' => array('publish')
304 ),
305 'per_page' => array(
306 'label' => __( 'Per page', 'permalink-manager' ),
307 'type' => 'number',
308 'default' => 10
309 )
310 );
311
312 // Fields for "Find and replace"
313 $find_and_replace = array(
314 'clearfix1' => array(
315 'type' => 'clearfix'
316 ),
317 'old_string' => array(
318 'label' => __( 'Find ...', 'permalink-manager' ),
319 'type' => 'text',
320 'container_class' => 'half'
321 ),
322 'new_string' => array(
323 'label' => __( 'Replace with ...', 'permalink-manager' ),
324 'type' => 'text',
325 'container_class' => 'half half2'
326 ),
327 'clearfix2' => array(
328 'type' => 'clearfix'
329 ),
330 'variant' => array(
331 'label' => __( 'Select which elements should be affected', 'permalink-manager' ),
332 'type' => 'radio',
333 'choices' => array('both' => '<strong>' . __('Plugin Slugs & Bases (Full URIs)', 'permalink-manager') . '</strong>', 'slugs' => '<strong>' . __('Only Plugin Slugs', 'permalink-manager') . '</strong>', 'post_names' => '<strong>' . __('Plugin Slugs & Wordpress Native Slugs (Post Names)', 'permalink-manager') . '</strong>'),
334 'default' => array('slugs'),
335 'desc' => __('First two options will affect settings used only by this plugin.<br />A MySQL backup is recommended before using third option - it overwrites the value of <strong>post_name</strong> field (part of <strong>$post</strong> object used by Wordpress core).', 'permalink-manager')
336 ),
337 'post_types' => array(
338 'label' => __( 'Post Types that should be affected', 'permalink-manager' ),
339 'type' => 'checkbox',
340 'choices' => array_merge(array('all' => '<strong>' . __('All Post Types', 'permalink-manager') . '</strong>'), $all_post_types),
341 'default' => array('post', 'page')
342 ),
343 'post_statuses' => array(
344 'label' => __( 'Post Statuses that should be affected', 'permalink-manager' ),
345 'type' => 'checkbox',
346 'choices' => array_merge(array('all' => '<strong>' . __('All Post Statuses', 'permalink-manager') . '</strong>'), $all_post_statuses_array),
347 'default' => array('publish')
348 )
349 );
350
351 // Fields for "Regenerate slugs"
352 $regenerate_slugs = array(
353 'variant' => array(
354 'label' => __( 'Select which elements should be affected', 'permalink-manager' ),
355 'type' => 'radio',
356 'choices' => array('both' => '<strong>' . __('Plugin Slugs & Bases (Full URIs)', 'permalink-manager') . '</strong>', 'slugs' => '<strong>' . __('Only Plugin Slugs', 'permalink-manager') . '</strong>', 'post_names' => '<strong>' . __('Plugin Slugs & Wordpress Native Slugs (Post Names)', 'permalink-manager') . '</strong>'),
357 'default' => array('slugs'),
358 'desc' => __('First two options will affect settings used only by this plugin.<br />A MySQL backup is recommended before using third option - it overwrites the value of <strong>post_name</strong> field (part of <strong>$post</strong> object used by Wordpress core).', 'permalink-manager')
359 ),
360 'post_types' => array(
361 'label' => __( 'Post Types that should be affected', 'permalink-manager' ),
362 'type' => 'checkbox',
363 'choices' => array_merge(array('all' => '<strong>' . __('All Post Types', 'permalink-manager') . '</strong>'), $all_post_types),
364 'default' => array('post', 'page')
365 ),
366 'post_statuses' => array(
367 'label' => __( 'Post Statuses that should be affected', 'permalink-manager' ),
368 'type' => 'checkbox',
369 'choices' => array_merge(array('all' => '<strong>' . __('All Post Statuses', 'permalink-manager') . '</strong>'), $all_post_statuses_array),
370 'default' => array('publish')
371 )
372 );
373
374 return isset($array) ? ${$array} : array();
375
376 }
377
378 /**
379 * Bulk actions functions
380 */
381 function bulk_actions() {
382 global $wpdb;
383
384 // Trigger a selected function
385 if (isset($_POST['update_all_slugs'])) {
386 $output = Permalink_Manager_Actions::update_all_permalinks();
387 } else if (isset($_POST['find-replace-button'])) {
388 $output = Permalink_Manager_Actions::find_replace($this->fields_arrays('find_and_replace'));
389 } else if (isset($_POST['regenerate-button'])) {
390 $output = Permalink_Manager_Actions::regenerate_all_permalinks();
391 // Save Permalink Structures/Permalinks Bases
392 } else if (isset($_POST['save_permastructs'])) {
393 $output = Permalink_Manager_Actions::update_permastructs();
394 }
395
396 // Load variables
397 $updated_array = isset($output['updated']) ? $output['updated'] : array();
398 $updated_slugs_count = isset($output['updated_count']) ? $output['updated_count'] : 0;
399 $alert_content = isset($output['alert_content']) ? $output['alert_content'] : "";
400 $alert_type = isset($output['alert_type']) ? $output['alert_type'] : "";
401
402 /**
403 * Display results
404 */
405 if((isset($_POST['permalink-manager']) || isset($_POST['update_all_slugs'])) && !(isset($_POST['screen-options-apply']))) {
406 // Display errors or success message
407
408 // Check how many rows/slugs were affected
409 if (isset($_POST['save_permastructs'])) {
410 $alert_type = 'updated';
411 $alert_content = __( 'Permastructures were updated!', 'permalink-manager' ) . ' ';
412 } else if($updated_slugs_count > 0) {
413 $alert_type = 'updated';
414 $alert_content = sprintf( _n( '<strong>%d</strong> slug were updated!', '<strong>%d</strong> slugs were updated!', $updated_slugs_count, 'permalink-manager' ), $updated_slugs_count ) . ' ';
415 $alert_content .= sprintf( __( '<a href="%s">Click here</a> to go to the list of updated slugs', 'permalink-manager' ), '#updated-list');
416 } else {
417 $alert_type = 'error';
418 $alert_content = ($alert_content) ? $alert_content : __( '<strong>No slugs</strong> were updated!', 'permalink-manager' );
419 }
420
421 Permalink_Manager_Helper_Functions::display_alert($alert_content, $alert_type, true);
422
423 // Display summary after update
424 // Display only if there are any slugs updated
425 if ( $updated_slugs_count > 0 && is_array($updated_array) ) {
426 add_filter('permalink-manager-after-tabs', function( $arg ) use ( $alert_content, $alert_type, $updated_array ) {
427
428 // Check if slugs should be displayed
429 $first_slug = reset($updated_array);
430
431 $header_footer = '<tr>';
432 $header_footer .= '<th class="column-primary">' . __('Title', 'permalink-manager') . '</th>';
433 $header_footer .= '<th>' . __('Old URI', 'permalink-manager') . '</th>';
434 $header_footer .= '<th>' . __('New URI', 'permalink-manager') . '</th>';
435 $header_footer .= (isset($first_slug['old_slug'])) ? '<th>' . __('Old Slug', 'permalink-manager') . '</th>' : "";
436 $header_footer .= (isset($first_slug['new_slug'])) ? '<th>' . __('New Slug', 'permalink-manager') . '</th>' : "";
437 $header_footer .= '</tr>';
438
439 $updated_slugs_count = 0;
440 $main_content = "";
441 foreach($updated_array as $row) {
442 // Odd/even class
443 $updated_slugs_count++;
444 $alternate_class = ($updated_slugs_count % 2 == 1) ? ' class="alternate"' : '';
445 //$permalink = Permalink_Manager_Helper_Functions::get_correct_permalink($row[ 'ID' ]);
446 $permalink = home_url("{$row['new_uri']}");
447
448 $main_content .= "<tr{$alternate_class}>";
449 $main_content .= '<td class="row-title column-primary" data-colname="' . __('Title', 'permalink-manager') . '">' . $row['post_title'] . "<a target=\"_blank\" href=\"{$permalink}\"><small>{$permalink}</small></a>" . '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __('Show more details', 'permalink-manager') . '</span></button></td>';
450 $main_content .= '<td data-colname="' . __('Old URI', 'permalink-manager') . '">' . $row['old_uri'] . '</td>';
451 $main_content .= '<td data-colname="' . __('New URI', 'permalink-manager') . '">' . $row['new_uri'] . '</td>';
452 $main_content .= (isset($row['old_slug'])) ? '<td data-colname="' . __('Old Slug', 'permalink-manager') . '">' . $row['old_slug'] . '</td>' : "";
453 $main_content .= (isset($row['new_slug'])) ? '<td data-colname="' . __('New Slug', 'permalink-manager') . '">' . $row['new_slug'] . '</td>' : "";
454 $main_content .= '</tr>';
455 }
456
457 // Merge header, footer and content
458 $output = '<h3 id="updated-list">' . __('List of updated posts', 'permalink-manager') . '</h3>';
459 $output .= '<table class="widefat wp-list-table">';
460 $output .= "<thead>{$header_footer}</thead><tbody>{$main_content}</tbody><tfoot>{$header_footer}</tfoot>";
461 $output .= '</table>';
462
463 return $output ;
464
465 });
466 }
467 }
468 }
469
470 /**
471 * Change permalinks for posts, pages & custom post types
472 */
473 function custom_permalinks($permalink, $post) {
474 global $wp_rewrite, $permalink_manager;
475
476 $post = (is_integer($post)) ? get_post($post) : $post;
477 $post_type = $post->post_type;
478
479 // Do not change permalink of frontpage
480 if(get_option('page_on_front') == $post->ID) { return $permalink; }
481
482 $uris = $this->permalink_manager_uris;
483 if(isset($uris[$post->ID])) $permalink = home_url('/') . $uris[$post->ID];
484
485 return $permalink;
486 }
487
488 /**
489 * Used to optimize SQL queries amount instead of rewrite rules
490 */
491 function detect_post($query) {
492
493 global $wpdb;
494
495 // Used in debug mode
496 $old_query = $query;
497
498 // GET URL
499 $protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://';
500 // Fix for Wordpress installed in subdirectories
501 $url = str_replace(home_url(), "{$protocol}{$_SERVER['HTTP_HOST']}", "{$protocol}{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}");
502
503 // Check if it is correct URL
504 if (filter_var($url, FILTER_VALIDATE_URL)) {
505
506 // Separate endpoints (if set) - support for comment pages will be added later
507 preg_match("/(.*)\/(page|feed|embed|attachment|track)\/(.*)/", $url, $url_with_endpoints);
508 if(isset($url_with_endpoints[3]) && !(empty($url_with_endpoints[3]))) {
509 $url = $url_with_endpoints[1];
510 $endpoint = str_replace(array('page', 'trackback'), array('paged', 'tb'), $url_with_endpoints[2]);
511 $endpoint_value = $url_with_endpoints[3];
512 }
513
514 // Parse URL
515 $url_parts = parse_url($url);
516 $uri = (isset($url_parts['path'])) ? trim($url_parts['path'], "/") : "";
517 if(empty($uri)) return $query;
518
519 // Check if current URL is assigned to any post
520 $uris = $this->permalink_manager_uris;
521 if(!(is_array($uris))) return $query;
522 $post_id = array_search($uri, $uris);
523
524 if(isset($post_id) && is_numeric($post_id)) {
525 // Check if it is revision (hotfix) and use original post ID instead of revision ID
526 $is_revision = wp_is_post_revision($post_id);
527 $post_id = ($is_revision) ? $is_revision : $post_id;
528
529 $post_to_load = get_post($post_id);
530 $original_page_uri = $post_to_load->post_name;
531 $post_type = $post_to_load->post_type;
532 unset($query['attachment']);
533 unset($query['error']);
534
535 // Fix for hierarchical CPT & pages
536 if( isset($post_to_load->ancestors) && !(empty($post_to_load->ancestors))) {
537 foreach ( $post_to_load->ancestors as $parent ) {
538 $parent = get_post( $parent );
539 if ( $parent && $parent->post_name ) {
540 $original_page_uri = $parent->post_name . '/' . $original_page_uri;
541 }
542 }
543 }
544
545 // Alter query parameters
546 if($post_to_load->post_type == 'page') {
547 $query['pagename'] = $original_page_uri;
548 } else if($post_to_load->post_type == 'post') {
549 $query['name'] = $original_page_uri;
550 } else {
551 $query['name'] = $original_page_uri;
552 $query['post_type'] = $post_type;
553 $query[$post_type] = $original_page_uri;
554 }
555
556 // Add endpoint
557 if(isset($endpoint_value) && !(empty($endpoint_value))) {
558 $query[$endpoint] = $endpoint_value;
559 }
560 }
561
562 }
563
564 // Debug mode
565 if(isset($_REQUEST['debug_url']) && $_REQUEST['debug_url'] == true) {
566 $debug_info['old_query_vars'] = $old_query;
567 $debug_info['new_query_vars'] = $query;
568 //$debug_info['request'] = "{$protocol}{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
569 $debug_info['request'] = $url;
570
571 $debug_txt = json_encode($debug_info);
572 $debug_txt = "<textarea style=\"width:100%;height:300px\">{$debug_txt}</textarea>";
573 wp_die($debug_txt);
574 }
575
576 return $query;
577 }
578
579 function redirect_to_new_uri() {
580 global $wp;
581
582 $uris = $this->permalink_manager_uris;
583 $object_id = get_queried_object_id();
584 $uri = isset($uris[$object_id]) ? home_url('/') . $uris[$object_id] : "";
585
586 $protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://';
587 $request_uri = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER["REQUEST_URI"];
588
589 // Get the option value (will be added in 0.5 with additional option panel)
590 $redirects_activated = 1;
591
592 // Ignore default URIs
593 if(!($uri)) return;
594
595 // Now get native URI & $_GET parameters
596 $old_default_uri = home_url('/') . Permalink_Manager_Helper_Functions::get_uri($object_id, 'native');
597 $correct_uri = str_replace($old_default_uri, $uri, $request_uri);
598
599 // Fix redirection loop and .html suffix issues
600 if(substr($correct_uri, -1) != '/' && substr($correct_uri, -4) != 'html') {
601 $correct_uri .= '/';
602 } else if(substr($correct_uri, -5) == 'html/') {
603 $correct_uri = strstr($correct_uri, '.html', true) . '.html';
604 }
605
606 if (isset($_REQUEST['debug_redirect'])) {
607 wp_die("<strong>ID:</strong> {$object_id}<br /> <strong>URI:</strong> {$uri}<br/> <strong>Default URI:</strong> {$old_default_uri}<br /><strong>Correct URI:</strong> {$correct_uri}<br /><strong>Request URI</strong>{$request_uri}");
608 // Redirect if it is old URI
609 } else if(strpos($request_uri, $old_default_uri) !== false && ($redirects_activated == 1)) {
610 wp_redirect( $correct_uri, 301 );
611 exit();
612 }
613
614 }
615
616 /**
617 * Allow to edit URIs from "Edit Post" admin pages
618 */
619 function edit_uri_box($html, $id, $new_title, $new_slug) {
620
621 global $post;
622
623 // Do not change anything if post is not saved yet
624 if(empty($post->post_name)) return $html;
625
626 $uris = $this->permalink_manager_uris;
627 $default_uri = trim(str_replace(home_url("/"), "", get_permalink($id)), "/");
628 $uri = (isset($uri[$id])) ? $uri[$id] : $default_uri;
629
630 $html = preg_replace("/(<strong>(.*)<\/strong>)(.*)/is", "$1 ", $html);
631 $html .= home_url("/") . " <span id=\"editable-post-name\"><input type='text' value='{$uri}' name='custom_uri'/></span>";
632 return $html;
633 }
634
635 /**
636 * Update URI from "Edit Post" admin page
637 */
638 function update_single_uri($post_id, $post, $update) {
639
640 // Ignore trashed items
641 if($post->post_status == 'trash') return;
642
643 // Fix for revisions
644 $is_revision = wp_is_post_revision($post_id);
645 $post_id = ($is_revision) ? $is_revision : $post_id;
646 $post = get_post($post_id);
647
648 $uris = $this->permalink_manager_uris;
649
650 $old_default_uri = Permalink_Manager_Helper_Functions::get_uri($post, 'native');
651 $old_uri = (isset($uris[$post->ID])) ? $uris[$post->ID] : $old_default_uri;
652
653 $new_default_uri = Permalink_Manager_Helper_Functions::get_uri($post, true);
654 $new_uri = '';
655
656 // Check if user changed URI (available after post is saved)
657 if(isset($_POST['custom_uri'])) {
658 $new_uri = trim($_POST['custom_uri'], "/");
659 }
660
661 // A little hack (if user removes whole URI from input)
662 $new_uri = ($new_uri) ? $new_uri : $new_default_uri;
663
664 // Do not store default values
665 if(isset($uris[$post->ID]) && ($new_uri == $old_default_uri)) {
666 unset($uris[$post->ID]);
667 } else if ($new_uri != $old_default_uri) {
668 $uris[$post->ID] = $new_uri;
669 }
670
671
672 update_option('permalink-manager-uris', $uris);
673 }
674
675 /**
676 * Debug helper function
677 */
678 function debug_functions() {
679 global $wp_filter;
680
681 if(isset($_REQUEST['debug_filter'])) {
682 $hook = $_REQUEST['debug_filter'];
683 $debug_txt = ($_REQUEST['debug_filter'] == "all") ? json_encode($wp_filter) : json_encode($wp_filter[$hook]);
684 $debug_txt = "<textarea style=\"width:100%;height:300px\">{$debug_txt}</textarea>";
685 wp_die($debug_txt);
686 } else if(isset($_REQUEST['debug_options'])) {
687 $options = get_option($_REQUEST['debug_options']);
688 $debug_txt = print_r($options, true);
689 $debug_txt = "<textarea style=\"width:100%;height:300px\">{$debug_txt}</textarea>";
690 wp_die($debug_txt);
691 }
692 }
693
694 /**
695 * Convert old plugin structure to the new solution (this function will be removed in 1.0 version)
696 */
697 function upgrade_plugin() {
698
699 global $wpdb;
700
701 /*
702 * Separate slugs from rest of plugin options
703 */
704 $options = $this->permalink_manager_options;
705 //if !empty($this->permalink_manager_options['base-editor'])
706 if (isset($options['base-editor']) && is_array($options['base-editor'])) {
707 $old_permastructs = $options['base-editor'];
708 $new_permastructs = $uris = array();
709
710 // At first save permastructs to new separate option field
711 foreach($old_permastructs as $post_type => $permastruct) {
712 $new_permastructs[$post_type] = trim(str_replace(Permalink_Manager_Helper_Functions::get_post_tag($post_type), '', $permastruct), "/");
713 }
714 unset($options['base-editor']);
715
716 // Grab posts from database
717 $sql_query = "SELECT * FROM {$wpdb->posts} WHERE post_status IN ('publish') LIMIT 99999";
718 $posts = $wpdb->get_results($sql_query);
719
720 foreach($posts as $post) {
721 $uri = Permalink_Manager_Helper_Functions::get_uri($post, true);
722
723 // Do not save default permastructures
724 $default_permastruct = trim( Permalink_Manager_Helper_Functions::get_default_permastruct($post_type), "/" );
725 if ($permastruct != $default_permastruct) $uris[$post->ID] = trim($uri, "/");
726 }
727
728 // Save new option fields
729 update_option('permalink-manager-uris', $uris);
730 update_option('permalink-manager', $options);
731 update_option('permalink-manager-permastructs', $new_permastructs);
732
733 // Reset rewrite rules
734 flush_rewrite_rules();
735 }
736 }
737 }
738
739 /**
740 * Begins execution of the plugin.
741 */
742 function run_permalink_manager() {
743
744 // Load plugin files.
745 require_once PERMALINK_MANAGER_DIR . '/inc/permalink-manager-editor.php';
746 require_once PERMALINK_MANAGER_DIR . '/inc/permalink-manager-base-editor.php';
747 require_once PERMALINK_MANAGER_DIR . '/inc/permalink-manager-screen-options.php';
748 require_once PERMALINK_MANAGER_DIR . '/inc/permalink-manager-helper-functions.php';
749 require_once PERMALINK_MANAGER_DIR . '/inc/permalink-manager-actions.php';
750
751 $Permalink_Manager_Class = new Permalink_Manager_Class();
752 $Permalink_Manager_Screen_Options = new Permalink_Manager_Screen_Options();
753
754 }
755
756 run_permalink_manager();
757