PluginProbe ʕ •ᴥ•ʔ
Permalink Manager Lite / 0.5.3
Permalink Manager Lite v0.5.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 includes 9 years ago js 9 years ago languages 9 years ago out 9 years ago LICENSE.txt 9 years ago README.txt 9 years ago permalink-manager.php 9 years ago
permalink-manager.php
277 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.5.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 // If this file is called directly, abort.
16 if ( ! defined( 'WPINC' ) ) {
17 die;
18 }
19
20 // Define the directories used to load plugin files.
21 define( 'PERMALINK_MANAGER_PLUGIN_NAME', 'Permalink Manager' );
22 define( 'PERMALINK_MANAGER_PLUGIN_SLUG', 'permalink-manager' );
23 define( 'PERMALINK_MANAGER_VERSION', '0.5.3' );
24 define( 'PERMALINK_MANAGER_DIR', untrailingslashit( dirname( __FILE__ ) ) );
25 define( 'PERMALINK_MANAGER_BASENAME', plugin_basename(__FILE__) );
26 define( 'PERMALINK_MANAGER_URL', untrailingslashit( plugins_url( '', __FILE__ ) ) );
27 define( 'PERMALINK_MANAGER_WEBSITE', 'http://maciejbis.net' );
28
29 class Permalink_Manager_Class {
30
31 public $permalink_manager, $permalink_manager_options_page, $permalink_manager_options;
32 public $sections, $functions, $permalink_manager_before_sections_html, $permalink_manager_after_sections_html;
33
34 /**
35 * Get options from DB, load subclasses & hooks
36 */
37 public function __construct() {
38 $this->include_subclassess();
39 $this->run_subclasses();
40 $this->register_init_hooks();
41 }
42
43 /**
44 * Include back-end classess and set their instances
45 */
46 function include_subclassess() {
47 // Load back-end functions
48 foreach(array('helper-functions', 'post-uri-functions', 'admin-functions', 'uri-actions') as $class) {
49 require_once PERMALINK_MANAGER_DIR . "/includes/core/permalink-manager-{$class}.php";
50 }
51
52 // WP_List_Table needed for post types & taxnomies editors
53 if( ! class_exists( 'WP_List_Table' ) ) {
54 require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
55 }
56
57 // Load section classes
58 foreach(array('uri-editor', 'tools', 'permastructs', 'settings', 'advanced') as $class) {
59 require_once PERMALINK_MANAGER_DIR . "/includes/views/permalink-manager-{$class}.php";
60 }
61 }
62
63 /**
64 * Load front-end classes and set their instances.
65 */
66 function run_subclasses() {
67 $this->functions['helper_functions'] = new Permalink_Manager_Helper_Functions();
68 $this->functions['admin_functions'] = new Permalink_Manager_Admin_Functions();
69 $this->functions['post_uri_functions'] = new Permalink_Manager_Post_URI_Functions();
70 $this->functions['uri_actions'] = new Permalink_Manager_Uri_Actions();
71 $this->sections['uri_editor'] = new Permalink_Manager_Uri_Editor();
72 $this->sections['tools'] = new Permalink_Manager_Tools();
73 $this->sections['permastructs'] = new Permalink_Manager_Permastructs();
74 $this->sections['settings'] = new Permalink_Manager_Settings();
75 $this->sections['advanced'] = new Permalink_Manager_Advanced();
76 }
77
78 /**
79 * Register general hooks
80 */
81 public function register_init_hooks() {
82 // Localize plugin
83 add_action( 'plugins_loaded', array($this, 'localize_me'), 1 );
84
85 // Load options
86 add_action( 'init', array($this, 'get_options_and_globals'), 1 );
87
88 // Use the URIs set in this plugin + redirect from old URIs to new URIs + adjust canonical redirect settings
89 add_action( 'wp', array($this, 'disable_canonical_redirect'), 0, 1 );
90 add_action( 'template_redirect', array($this, 'redirect_to_new_uri'), 999);
91 add_filter( 'request', array($this, 'detect_post'), 0, 1 );
92 }
93
94 /**
95 * Localize this plugin
96 */
97 function localize_me() {
98 load_plugin_textdomain( 'permalink-manager', false, PERMALINK_MANAGER_DIR );
99 }
100
101 /**
102 * Get options values & set global
103 */
104 public function get_options_and_globals() {
105 // 1. Globals with data stored in DB
106 global $permalink_manager_options, $permalink_manager_uris, $permalink_manager_permastructs;
107
108 $this->permalink_manager_options = $permalink_manager_options = apply_filters('permalink-manager-options', get_option('permalink-manager'));
109 $this->permalink_manager_uris = $permalink_manager_uris = apply_filters('permalink-manager-uris', get_option('permalink-manager-uris'));
110 $this->permalink_manager_permastructs = $permalink_manager_permastructs = apply_filters('permalink-manager-permastructs', get_option('permalink-manager-permastructs'));
111
112 // 2. Globals used to display additional content (eg. alerts)
113 global $permalink_manager_before_sections_html, $permalink_manager_after_sections_html;
114
115 $this->permalink_manager_before_sections_html = $permalink_manager_before_sections_html = apply_filters('permalink-manager-before-sections', '');
116 $this->permalink_manager_after_sections_html = $permalink_manager_after_sections_html = apply_filters('permalink-manager-after-sections', '');
117 }
118
119 /**
120 * Used to optimize SQL queries amount instead of rewrite rules - the essential part of this plugin
121 */
122 function detect_post($query) {
123 global $wpdb, $permalink_manager_uris;
124
125 // Used in debug mode
126 $old_query = $query;
127
128 $protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://';
129 $url = str_replace(home_url(), "{$protocol}{$_SERVER['HTTP_HOST']}", "{$protocol}{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"); // Fix for Wordpress installed in subdirectories
130
131 // Remove .html suffix from URL and query (URLs ended with .html work as aliases)
132 $url = str_replace(".html", "", $url);
133 if(isset($query['name'])) { $query['name'] = str_replace('.html', '', $query['name']); }
134 if(isset($query['pagename'])) { $query['pagename'] = str_replace('.html', '', $query['pagename']); }
135
136 // Check if it is correct URL
137 if (filter_var($url, FILTER_VALIDATE_URL)) {
138 // Separate endpoints (if set) - support for comment pages will be added later
139 preg_match("/(.*)\/(page|feed|embed|attachment|track)\/(.*)/", $url, $url_with_endpoints);
140 if(isset($url_with_endpoints[3]) && !(empty($url_with_endpoints[3]))) {
141 $url = $url_with_endpoints[1];
142 $endpoint = str_replace(array('page', 'trackback'), array('paged', 'tb'), $url_with_endpoints[2]);
143 $endpoint_value = $url_with_endpoints[3];
144 }
145
146 // Parse URL
147 $url_parts = parse_url($url);
148 $uri = (isset($url_parts['path'])) ? trim($url_parts['path'], "/") : "";
149 if(empty($uri)) return $query;
150
151 // Check if current URL is assigned to any post
152 if(!(is_array($permalink_manager_uris))) return $query;
153 $post_id = array_search($uri, $permalink_manager_uris);
154
155 // Check again in case someone added .html suffix to particular post (with .html suffix)
156 $post_id = (empty($post_id)) ? array_search("{$uri}.html", $permalink_manager_uris) : $post_id;
157
158 if(isset($post_id) && is_numeric($post_id)) {
159 // Check if it is revision (hotfix) and use original post ID instead of revision ID
160 $is_revision = wp_is_post_revision($post_id);
161
162 // Debug for @andresgl
163 if(isset($_REQUEST['debug_detect_post'])) {
164 $post_to_load = (is_object(get_post($post_id))) ? get_post($post_id) : 'no object!';
165 $revision_post_to_load = (is_object(get_post($is_revision))) ? get_post($is_revision) : 'no object!';
166
167 $debug_array = array(
168 'original_post_id' => $post_id,
169 'original_post' => $post_to_load,
170 'revision_post_id' => $is_revision,
171 'revision_post' => $revision_post_to_load,
172 );
173
174 wp_die("<pre>" . print_r($debug_array, true) . "</pre>");
175 }
176
177 $post_id = ($is_revision) ? $is_revision : $post_id;
178
179 $post_to_load = get_post($post_id);
180 $original_page_uri = $post_to_load->post_name;
181 $post_type = $post_to_load->post_type;
182 unset($query['attachment']);
183 unset($query['error']);
184
185 // Fix for hierarchical CPT & pages
186 if( isset($post_to_load->ancestors) && !(empty($post_to_load->ancestors))) {
187 foreach ( $post_to_load->ancestors as $parent ) {
188 $parent = get_post( $parent );
189 if ( $parent && $parent->post_name ) {
190 $original_page_uri = $parent->post_name . '/' . $original_page_uri;
191 }
192 }
193 }
194
195 // Fix for not-pages
196 if($post_to_load->post_type != 'post') {
197 unset($query['year']);
198 unset($query['monthnum']);
199 unset($query['day']);
200 }
201
202 // Alter query parameters
203 if($post_to_load->post_type == 'page') {
204 unset($query['name']);
205 $query['pagename'] = $original_page_uri;
206 } else if($post_to_load->post_type == 'post') {
207 $query['name'] = $original_page_uri;
208 } else {
209 $query['name'] = $original_page_uri;
210 $query['post_type'] = $post_type;
211 $query[$post_type] = $original_page_uri;
212 }
213
214 // Make the redirects more clever - see redirect_to_new_uri() method
215 $query['do_not_redirect'] = 1;
216
217 // Add endpoint
218 if(isset($endpoint_value) && !(empty($endpoint_value))) {
219 $query[$endpoint] = $endpoint_value;
220 }
221 }
222 }
223
224 // Debug mode
225 if(isset($_REQUEST['debug_url'])) {
226 $debug_info['old_query_vars'] = $old_query;
227 $debug_info['new_query_vars'] = $query;
228 //$debug_info['request'] = "{$protocol}{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
229 $debug_info['request'] = $url;
230
231 $debug_txt = json_encode($debug_info);
232 $debug_txt = "<textarea style=\"width:100%;height:300px\">{$debug_txt}</textarea>";
233 wp_die($debug_txt);
234 }
235
236 return $query;
237 }
238
239 function redirect_to_new_uri() {
240 global $wp, $wp_query, $permalink_manager_uris, $permalink_manager_options;
241
242 // Affect only posts with custom URI and old URIs
243 if(is_singular() && isset($permalink_manager_uris[$wp_query->queried_object_id]) && empty($wp_query->query['do_not_redirect'])) {
244 $current_url = home_url(add_query_arg(array(),$wp->request));
245 $native_uri = Permalink_Manager_Post_URI_Functions::get_default_post_uri($wp_query->queried_object_id, true);
246
247 $active_permalink = str_replace($native_uri, $permalink_manager_uris[$wp_query->queried_object_id], $current_url);
248 }
249
250 // Get the redirection mode
251 $redirect_mode = $permalink_manager_options['miscellaneous']['redirect'];
252
253 // Ignore default URIs (or do nothing if redirects are disabled)
254 if(!empty($active_permalink) && !empty($redirect_mode)) {
255 wp_redirect($active_permalink, $redirect_mode);
256 exit();
257 }
258 }
259
260 function disable_canonical_redirect() {
261 global $permalink_manager_options;
262 if(!($permalink_manager_options['miscellaneous']['canonical_redirect'])) {
263 remove_action('template_redirect', 'redirect_canonical');
264 }
265 }
266
267 }
268
269 /**
270 * Begins execution of the plugin.
271 */
272 function run_permalink_manager() {
273 $Permalink_Manager_Class = new Permalink_Manager_Class();
274 }
275
276 run_permalink_manager();
277