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