Permalink Manager Lite - Version 1.0.0

Version Description

  • Further refactoring
  • WPML support added
  • Some minor issues fixed
  • "Sample permalink" support added
Download this release

Release Info

Developer mbis
Plugin Icon 128x128 Permalink Manager Lite
Version 1.0.0
Comparing to
See all releases

Code changes from version 0.5.3 to 1.0.0

README.txt CHANGED
@@ -4,10 +4,10 @@ License: GPLv3
4
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
5
  Tags: urls, permalinks, slugs, custom url, custom permalinks, uris, url, slug, permalink
6
  Requires at least: 4.0
7
- Tested up to: 4.7.2
8
- Stable tag: 0.5.3
9
 
10
- Permalink Manager helps to maintain and bulk regenerate or "find and replace" any word in your permalinks & slugs.
11
 
12
  == Description ==
13
 
@@ -66,20 +66,22 @@ After the plugin is installed you can access its dashboard from this page: `Tool
66
 
67
  1. "Permalink editor".
68
  2. "Find and replace" section.
69
- 3. "Regenerate/Reset" section.
70
  4. "Permastructures" section.
71
  5. A list of updated posts.
72
  6. Editable URI box in Post/Page/CPT edit pagees.
73
  7. Settings section.
74
  8. Developer section.
75
 
76
- == Frequently Asked Questions ==
77
-
78
- = Q. Does the plugin support WPML/qTranslate
79
- = A. Unfortunately not, the WPML/qTranslate support will be added in next versions.
80
 
81
  == Changelog ==
82
 
 
 
 
 
 
 
83
  = 0.5.2/0.5.3 =
84
  * Another hotfix
85
 
4
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
5
  Tags: urls, permalinks, slugs, custom url, custom permalinks, uris, url, slug, permalink
6
  Requires at least: 4.0
7
+ Tested up to: 4.7.3
8
+ Stable tag: 1.0.0
9
 
10
+ Most advanced yet easy-to-use permalink plugin that helps to maintain & bulk change your URLs & slugs.
11
 
12
  == Description ==
13
 
66
 
67
  1. "Permalink editor".
68
  2. "Find and replace" section.
69
+ 3. "Regenerate/Reset" section.
70
  4. "Permastructures" section.
71
  5. A list of updated posts.
72
  6. Editable URI box in Post/Page/CPT edit pagees.
73
  7. Settings section.
74
  8. Developer section.
75
 
 
 
 
 
76
 
77
  == Changelog ==
78
 
79
+ = 1.0.0 =
80
+ * Further refactoring
81
+ * WPML support added
82
+ * Some minor issues fixed
83
+ * "Sample permalink" support added
84
+
85
  = 0.5.2/0.5.3 =
86
  * Another hotfix
87
 
css/permalink-manager-admin.css DELETED
@@ -1,35 +0,0 @@
1
- /**
2
- * Permalink Manager Table CSS
3
- */
4
- #permalinks-table-wrap { }
5
-
6
- #permalinks-table-wrap #plugin-name-heading a { color: #959595; font-size: 60%; text-decoration: none; }
7
-
8
- #permalinks-table-wrap .tablenav { margin: 6px 0 15px; }
9
- #permalinks-table-wrap .column-post_type, #permalinks-table-wrap .column-post_status { width: 10%; }
10
- #permalinks-table-wrap .post_name input { max-width: 100%; }
11
- #permalinks-table-wrap .post_permalink a, #permalinks-table-wrap .post_permalink .dashicons { font-size: 13px; color: #aaa; line-height: 1.5em; }
12
-
13
- #permalinks-table-wrap .alert { line-height: 19px; padding: 11px 15px; margin: 15px 0; }
14
- #permalinks-table-wrap .alert p { margin-top: 0; line-height: 200%; }
15
- #permalinks-table-wrap .alert ul, #permalinks-table-wrap .alert ol { margin-top: 0; margin-bottom: 0; }
16
- #permalinks-table-wrap .alert p:last-of-type, #permalinks-table-wrap .alert li:last-of-type { margin-bottom: 0; }
17
- #permalinks-table-wrap .warning { background: #dc3232; }
18
- #permalinks-table-wrap .warning, #permalinks-table-wrap .warning a { color: #fff; }
19
- #permalinks-table-wrap .info { background: #f9f9f9; }
20
-
21
- #permalinks-table-wrap #permalink-manager-tabs > div { display: none; }
22
- #permalinks-table-wrap #permalink-manager-tabs > div.show { display: block; }
23
-
24
- #permalinks-table-wrap #permalink-manager-tabs td label { display: block; }
25
-
26
- #permalinks-table-wrap small{ display: block; font-weight: normal; color: #888; }
27
-
28
- #permalink-manager-tabs {}
29
- #permalink-manager-tabs h4 { margin-bottom: 5px; font-size: 16px; }
30
- #permalink-manager-tabs .field-container { margin-bottom: 30px; }
31
- #permalink-manager-tabs .field-container .field-desc { font-style: italic; }
32
- #permalink-manager-tabs .half { width: 48%; float: left; }
33
- #permalink-manager-tabs .half2 { margin-left: 4%; }
34
- #permalink-manager-tabs .half input { width: 100%; }
35
- #permalink-manager-tabs .clearfix { float: none; overflow: hidden; clear: both; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/core/permalink-manager-actions.php ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Additional hooks for "Permalink Manager Pro"
4
+ */
5
+ class Permalink_Manager_Actions extends Permalink_Manager_Class {
6
+
7
+ public function __construct() {
8
+ add_action( 'admin_init', array($this, 'trigger_action'), 999 );
9
+ add_action( 'admin_init', array($this, 'clear_uris') );
10
+ }
11
+
12
+ /**
13
+ * Actions
14
+ */
15
+ public function trigger_action() {
16
+ global $permalink_manager_before_sections_html, $permalink_manager_after_sections_html;
17
+
18
+ // 1. Check if the form was submitted
19
+ if(empty($_POST)) { return; }
20
+
21
+ $actions_map = array(
22
+ 'uri_editor' => array('function' => 'update_all_permalinks', 'display_uri_table' => true),
23
+ 'regenerate' => array('function' => 'regenerate_all_permalinks', 'display_uri_table' => true),
24
+ 'find_and_replace' => array('function' => 'find_and_replace', 'display_uri_table' => true),
25
+ 'permalink_manager_options' => array('function' => 'save_settings'),
26
+ 'permalink_manager_permastructs' => array('function' => 'save_permastructures')
27
+ );
28
+ // Clear URIs & reset settings & permastructs also should be added here.
29
+
30
+ // 2. Find the action
31
+ foreach($actions_map as $action => $map) {
32
+ if(isset($_POST[$action]) && wp_verify_nonce($_POST[$action], 'permalink-manager')) {
33
+ $output = call_user_func(array($this, $map['function']));
34
+
35
+ // Get list of updated URIs
36
+ if(!empty($map['display_uri_table'])) {
37
+ $updated_slugs_count = (isset($output['updated_count']) && $output['updated_count'] > 0) ? $output['updated_count'] : false;
38
+ $updated_slugs_array = ($updated_slugs_count) ? $output['updated'] : '';
39
+ }
40
+
41
+ // Trigger only one function
42
+ break;
43
+ }
44
+ }
45
+
46
+ // 3. Display the slugs table (and append the globals)
47
+ if(isset($updated_slugs_count)) {
48
+ if($updated_slugs_count > 0) {
49
+ $updated_title = __('List of updated items', 'bis');
50
+ $alert_content = sprintf( _n( '<strong>%d</strong> slug was updated!', '<strong>%d</strong> slugs were updated!', $updated_slugs_count, 'permalink-manager' ), $updated_slugs_count ) . ' ';
51
+ $alert_content .= sprintf( __( '<a %s>Click here</a> to go to the list of updated slugs', 'permalink-manager' ), "href=\"#TB_inline?width=100%&height=600&inlineId=updated-list\" title=\"{$updated_title}\" class=\"thickbox\"");
52
+
53
+ $permalink_manager_before_sections_html .= Permalink_Manager_Admin_Functions::get_alert_message($alert_content, 'updated');
54
+ $permalink_manager_after_sections_html .= Permalink_Manager_Admin_Functions::display_updated_slugs($updated_slugs_array);
55
+ } else {
56
+ $alert_content = __( '<strong>No slugs</strong> were updated!', 'permalink-manager' );
57
+ $permalink_manager_before_sections_html .= Permalink_Manager_Admin_Functions::get_alert_message($alert_content, 'error');
58
+ }
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Save settings
64
+ */
65
+ public static function save_settings() {
66
+ global $permalink_manager_options;
67
+
68
+ $post_fields = $_POST;
69
+ $new_options = array();
70
+
71
+ foreach($post_fields as $option_name => $option_value) {
72
+ $new_options[$option_name] = $option_value;
73
+ }
74
+
75
+ // Override the global with settings
76
+ $permalink_manager_options = $new_options = array_filter($new_options);
77
+
78
+ // Save the settings in database
79
+ update_option('permalink-manager', $new_options);
80
+ }
81
+
82
+ /**
83
+ * Save permastructures
84
+ */
85
+ public static function save_permastructures() {
86
+ global $permalink_manager_permastructs;
87
+
88
+ $post_fields = $_POST;
89
+ $new_options = array();
90
+
91
+ foreach($post_fields as $option_name => $option_value) {
92
+ $new_options[$option_name] = $option_value;
93
+ }
94
+
95
+ // Trim the trailing slashes & remove empty permastructures
96
+ $new_options = Permalink_Manager_Helper_Functions::multidimensional_array_map('untrailingslashit', $new_options);
97
+ foreach($new_options as $group_name => $group) {
98
+ if(is_array($group)) {
99
+ $group = array_map('Permalink_Manager_Helper_Functions::remove_post_tag', $group);
100
+ $new_options[$group_name] = array_filter($group);
101
+ } else {
102
+ unset($new_options[$group_name]);
103
+ }
104
+ }
105
+
106
+ // Override the global with settings
107
+ $permalink_manager_permastructs = $new_options = array_filter($new_options);
108
+
109
+ // Save the settings in database
110
+ update_option('permalink-manager-permastructs', $new_options);
111
+ }
112
+
113
+ /**
114
+ * Remove URI from options array after post is moved to the trash
115
+ */
116
+ function clear_uris($post_id) {
117
+ global $permalink_manager_uris;
118
+
119
+ if(isset($_GET['clear-permalink-manager-uris']) && !empty($permalink_manager_uris)) {
120
+ foreach($permalink_manager_uris as $post_id => $uri) {
121
+ // Loop only through post URIs
122
+ if(is_numeric($post_id)) {
123
+ $post_status = get_post_status($post_id);
124
+ if(in_array($post_status, array('auto-draft', 'trash', ''))) {
125
+ unset($permalink_manager_uris[$post_id]);
126
+ }
127
+ }
128
+ }
129
+
130
+ update_option('permalink-manager-uris', $permalink_manager_uris);
131
+ }
132
+ }
133
+
134
+ /**
135
+ * "Find and replace" in "Tools"
136
+ */
137
+ function find_and_replace() {
138
+ // Check if posts or terms should be updated
139
+ if(!empty($_POST['section_type']) && $_POST['section_type'] == 'tax') {
140
+ return Permalink_Manager_URI_Functions_Tax::find_and_replace();
141
+ } else {
142
+ return Permalink_Manager_URI_Functions_Post::find_and_replace();
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Regenerate all permalinks in "Tools"
148
+ */
149
+ function regenerate_all_permalinks() {
150
+ // Check if posts or terms should be updated
151
+ if(!empty($_POST['section_type']) && $_POST['section_type'] == 'tax') {
152
+ return Permalink_Manager_URI_Functions_Tax::regenerate_all_permalinks();
153
+ } else {
154
+ return Permalink_Manager_URI_Functions_Post::regenerate_all_permalinks();
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Update all permalinks in "Permalink Editor"
160
+ */
161
+ function update_all_permalinks() {
162
+ // Check if posts or terms should be updated
163
+ if(!empty($_POST['section_type']) && $_POST['section_type'] == 'tax') {
164
+ return Permalink_Manager_URI_Functions_Tax::update_all_permalinks();
165
+ } else {
166
+ return Permalink_Manager_URI_Functions_Post::update_all_permalinks();
167
+ }
168
+ }
169
+
170
+ }
171
+
172
+ ?>
includes/core/permalink-manager-admin-functions.php CHANGED
@@ -1,488 +1,454 @@
1
  <?php
2
 
3
  /**
4
- * Additional back-end functions related to Wordpress Dashboard UI
5
- */
6
  class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
7
 
8
- public $menu_name, $sections, $active_section, $active_subsection;
9
- public $plugin_slug = PERMALINK_MANAGER_PLUGIN_SLUG;
10
- public $plugin_basename = PERMALINK_MANAGER_BASENAME;
11
-
12
- public function __construct() {
13
- add_action( "admin_menu", array($this, "add_menu_page") );
14
- add_action( 'admin_init', array($this, 'init') );
15
-
16
- // Allow to edit URIs in posts, pages & CPT elements
17
- add_filter( 'get_sample_permalink_html', array($this, 'edit_uri_box'), 999, 4 );
18
- }
19
-
20
- /**
21
- * Hooks that should be triggered with "admin_init"
22
- */
23
- public function init() {
24
- // Additional link in "Plugins" page
25
- add_filter( "plugin_action_links_{$this->plugin_basename}", array($this, "plugins_page_links") );
26
-
27
- // Detect current section
28
- $this->sections = apply_filters('permalink-manager-sections', array());
29
- $this->get_current_section();
30
-
31
- // Save settings
32
- $this->save_settings();
33
- }
34
-
35
- /**
36
- * Get current section (only in plugin sections)
37
- */
38
- public function get_current_section() {
39
- global $active_section, $active_subsection;
40
-
41
- // 1. Get current section
42
- if(isset($_GET['page']) && $_GET['page'] == $this->plugin_slug) {
43
- if(isset($_POST['section'])) {
44
- $this->active_section = $_POST['section'];
45
- } else if(isset($_GET['section'])) {
46
- $this->active_section = $_GET['section'];
47
- } else {
48
- $sections_names = array_keys($this->sections);
49
- $this->active_section = $sections_names[0];
50
- }
51
- }
52
-
53
- // 2. Get current subsection
54
- if($this->active_section && isset($this->sections[$this->active_section]['subsections'])) {
55
- if(isset($_POST['subsection'])) {
56
- $this->active_subsection = $_POST['subsection'];
57
- } else if(isset($_GET['subsection'])) {
58
- $this->active_subsection = $_GET['subsection'];
59
- } else {
60
- $subsections_names = array_keys($this->sections[$this->active_section]['subsections']);
61
- $this->active_subsection = $subsections_names[0];
62
- }
63
- }
64
-
65
- // Set globals
66
- $active_section = $this->active_section;
67
- $active_subsection = $this->active_subsection;
68
- }
69
-
70
- /**
71
- * Save settings
72
- */
73
- public function save_settings() {
74
- global $permalink_manager_options, $permalink_manager_permastructs;
75
-
76
- // Check if the form was submitted
77
- if(empty($_POST)) { return; }
78
-
79
- $post_fields = $_POST;
80
- $new_options = array();
81
- $helper_functions = new Permalink_Manager_Helper_Functions();
82
-
83
- // 1. Sanitize the field values
84
- foreach($post_fields as $option_name => $option_value) {
85
- //$new_options[$option_name] = $helper_functions->multidimensional_array_map('sanitize_text_field', $option_value);
86
- $new_options[$option_name] = $option_value;
87
- }
88
-
89
- // 2A. Save options/settings
90
- if(isset($_POST['permalink-manager-options']) && wp_verify_nonce($_POST['permalink-manager-options'], 'save_settings')) {
91
- // Override the global with settings
92
- $permalink_manager_options = $new_options = array_filter($new_options);
93
-
94
- // Save the settings in database
95
- update_option('permalink-manager', $new_options);
96
- }
97
- // 2B. Save permastructs
98
- else if(isset($_POST['permalink-manager-permastructs']) && wp_verify_nonce($_POST['permalink-manager-permastructs'], 'save_settings')) {
99
- // Trim the trailing slashes & remove empty permastructures
100
- $new_options = $helper_functions->multidimensional_array_map('untrailingslashit', $new_options['permastructures']);
101
- $new_options = array_filter($new_options);
102
-
103
- // Override the global with settings
104
- $permalink_manager_permastructs = $new_options;
105
-
106
- // Save the settings in database
107
- update_option('permalink-manager-permastructs', $new_options);
108
- }
109
- }
110
-
111
- /**
112
- * Add menu page.
113
- */
114
- public function add_menu_page() {
115
- $this->menu_name = add_management_page( __('Permalink Manager', 'permalink-manager'), __('Permalink Manager', 'permalink-manager'), 'manage_options', $this->plugin_slug, array($this, 'display_section') );
116
-
117
- // Make sure thata the CSS and JS files are loaded only on plugin admin page.
118
- add_action( 'admin_print_styles-' . $this->menu_name, array($this, 'enqueue_styles' ) );
119
- add_action( 'admin_print_scripts-' . $this->menu_name, array($this, 'enqueue_scripts' ) );
120
- }
121
-
122
- /**
123
- * Register the CSS file for the dashboard.
124
- */
125
- public function enqueue_styles() {
126
- wp_enqueue_style( $this->plugin_slug, PERMALINK_MANAGER_URL . '/out/permalink-manager-admin.css', array(), PERMALINK_MANAGER_VERSION, 'all' );
127
- }
128
-
129
- /**
130
- * Register the JavaScript file for the dashboard.
131
- */
132
- public function enqueue_scripts() {
133
- wp_enqueue_script( $this->plugin_slug, PERMALINK_MANAGER_URL . '/out/permalink-manager-admin.js', array( 'jquery' ), PERMALINK_MANAGER_VERSION, false );
134
- }
135
-
136
- /**
137
- * Get admin url for the plugin
138
- */
139
- function get_admin_url($append = '') {
140
- return menu_page_url( "{$this->plugin_slug}", false ) . $append;
141
- }
142
-
143
- /**
144
- * Additional links on "Plugins" page
145
- */
146
- public function plugins_page_links($links) {
147
- $links[] = '<a href="' . $this->get_admin_url() .'">' . __( 'Go To Permalink Manager', 'permalink-manager' ) . '</a>';
148
- return $links;
149
- }
150
-
151
- /**
152
- * Generate the fields
153
- */
154
- static public function generate_option_field($input_name, $args) {
155
- global $permalink_manager_options;
156
-
157
- // Reset $fields variables
158
- $fields = $section_name = $field_name = '';
159
-
160
- // Allow to filter the $args
161
- $args = apply_filters('permalink-manager-field-args', $args, $input_name);
162
-
163
- $default = (isset($args['default'])) ? $args['default'] : '';
164
- $label = (isset($args['label'])) ? $args['label'] : '';
165
- $placeholder = (isset($args['placeholder'])) ? "placeholder=\"{$args['placeholder']}\"" : '';
166
- $readonly = (isset($args['readonly'])) ? "readonly=\"readonly\"" : '';
167
- $rows = (isset($args['rows'])) ? "rows=\"{$rows}\"" : "rows=\"5\"";
168
- $input_class = (isset($args['input_class'])) ? "class=\"{$args['input_class']}\"" : '';
169
- $container_class = (isset($args['container_class'])) ? " class=\"{$args['container_class']} field-container\"" : " class=\"field-container\"";
170
- $description = (isset($args['description'])) ? "<p class=\"field-description description\">{$args['description']}</p>" : "";
171
- $append_content = (isset($args['append_content'])) ? "{$args['append_content']}" : "";
172
-
173
- // Get the field value (if it is not set in $args)
174
- if(isset($args['value']) && empty($args['value']) == false) {
175
- $value = $args['value'];
176
- } else {
177
- // Extract the section and field name from $input_name
178
- preg_match("/(.*)\[(.*)\]/", $input_name, $field_section_and_name);
179
-
180
- if($field_section_and_name) {
181
- $section_name = $field_section_and_name[1];
182
- $field_name = $field_section_and_name[2];
183
- $value = (isset($permalink_manager_options[$section_name][$field_name])) ? $permalink_manager_options[$section_name][$field_name] : $default;
184
- } else {
185
- $value = (isset($permalink_manager_options[$input_name])) ? $permalink_manager_options[$input_name] : $default;
186
- }
187
- }
188
-
189
- switch($args['type']) {
190
- case 'checkbox' :
191
- $fields .= '<div class="checkboxes">';
192
- foreach($args['choices'] as $choice_value => $checkbox_label) {
193
- $checked = (is_array($value) && in_array($choice_value, $value)) ? "checked='checked'" : "";
194
- $fields .= "<label for='{$input_name}[]'><input type='checkbox' {$input_class} value='{$choice_value}' name='{$input_name}[]' {$checked} /> {$checkbox_label}</label>";
195
- }
196
- $fields .= '</div>';
197
-
198
- // Add helper checkboxes for bulk actions
199
- if(isset($args['select_all']) || isset($args['unselect_all'])) {
200
- $select_all_label = (!empty($args['select_all'])) ? $args['select_all'] : __('Select all', 'permalink-manager');
201
- $unselect_all_label = (!empty($args['unselect_all'])) ? $args['unselect_all'] : __('Unselect all', 'permalink-manager');
202
-
203
- $fields .= "<p class=\"checkbox_actions extra-links\">";
204
- $fields .= (isset($args['select_all'])) ? "<a href=\"#\" class=\"select_all\">{$select_all_label}</a>&nbsp;" : "";
205
- $fields .= (isset($args['unselect_all'])) ? "<a href=\"#\" class=\"unselect_all\">{$unselect_all_label}</a>" : "";
206
- $fields .= "</p>";
207
- }
208
- break;
209
-
210
- case 'radio' :
211
- $fields .= '<div class="radios">';
212
- foreach($args['choices'] as $choice_value => $checkbox_label) {
213
- $checked = ($choice_value == $value) ? "checked='checked'" : "";
214
- $fields .= "<label for='{$input_name}[]'><input type='radio' {$input_class} value='{$choice_value}' name='{$input_name}[]' {$checked} /> {$checkbox_label}</label>";
215
- }
216
- $fields .= '</div>';
217
- break;
218
-
219
- case 'select' :
220
- $fields .= '<div class="select">';
221
- $fields .= "<select name='{$input_name}' {$input_class}>";
222
- foreach($args['choices'] as $choice_value => $checkbox_label) {
223
- $selected = ($choice_value == $value) ? "selected='selected'" : "";
224
- $fields .= "<option value='{$choice_value}' {$selected} />{$checkbox_label}</option>";
225
- }
226
- $fields .= '</select>';
227
- $fields .= '</div>';
228
- break;
229
-
230
- case 'number' :
231
- $fields .= "<input type='number' {$input_class} value='{$value}' name='{$input_name}' />";
232
- break;
233
-
234
- case 'textarea' :
235
- $fields .= "<textarea {$input_class} name='{$input_name}' {$placeholder} {$readonly} {$rows}>{$value}</textarea>";
236
- break;
237
-
238
- case 'pre' :
239
- $fields .= "<pre {$input_class}>{$value}</pre>";
240
- break;
241
-
242
- case 'clearfix' :
243
- return "<div class=\"clearfix\"></div>";
244
-
245
- default :
246
- $fields .= "<input type='text' {$input_class} value='{$value}' name='{$input_name}' {$placeholder} {$readonly}/>";
247
- }
248
-
249
- // Get the final HTML output
250
- if(isset($args['container']) && $args['container'] == 'tools') {
251
- $output = "<div{$container_class}>";
252
- $output .= "<h4>{$label}</h4>";
253
- $output .= "<div class='{$input_name}-container'>{$fields}</div>";
254
- $output .= $description;
255
- $output .= $append_content;
256
- $output .= "</div>";
257
- } else if(isset($args['container']) && $args['container'] == 'row') {
258
- $output = "<tr><th><label for='{$input_name}'>{$args['label']}</label></th>";
259
- $output .= "<td>{$fields}{$description}</td></tr>";
260
- $output .= ($append_content) ? "<tr class=\"appended-row\"><td colspan=\"2\">{$append_content}</td></tr>" : "";
261
- } else {
262
- $output = $fields . $append_content;
263
- }
264
-
265
- return apply_filters('permalink-manager-field-output', $output);
266
- }
267
-
268
- /**
269
- * Allow to edit URIs from "Edit Post" admin pages
270
- */
271
- function edit_uri_box($html, $id, $new_title, $new_slug) {
272
- global $post, $permalink_manager_uris;
273
-
274
- // Do not change anything if post is not saved yet
275
- if(empty($post->post_name)) return $html;
276
- $default_uri = trim(str_replace(home_url("/"), "", get_permalink($id)), "/");
277
- $uri = (!empty($permalink_manager_uris[$id])) ? $permalink_manager_uris[$id] : $default_uri;
278
-
279
- $html = preg_replace("/(<strong>(.*)<\/strong>)(.*)/is", "$1 ", $html);
280
- $html .= home_url("/") . " <span id=\"editable-post-name\"><input type='text' value='{$uri}' name='custom_uri'/></span>";
281
- return $html;
282
- }
283
-
284
- /**
285
- * Display the form
286
- */
287
- static public function get_the_form($fields = array(), $container = '', $button = array(), $sidebar = '', $nonce = array()) {
288
- // 1. Check if the content will be displayed in columns and button details
289
- switch($container) {
290
- case 'columns-3' :
291
- $wrapper_class = 'columns-container';
292
- $form_column_class = 'column column-2_3';
293
- $sidebar_class = 'column column-1_3';
294
- break;
295
- // there will be more cases in future ...
296
- default :
297
- $wrapper_class = $form_column_class = $sidebar_class = '';
298
- }
299
-
300
- // 2. Process the array with button and nonce field settings
301
- $button_text = (!empty($button['text'])) ? $button['text'] : '';
302
- $button_class = (!empty($button['class'])) ? $button['class'] : '';
303
- $nonce_action = (!empty($nonce['action'])) ? $nonce['action'] : '';
304
- $nonce_name = (!empty($nonce['name'])) ? $nonce['name'] : '';
305
-
306
- // 2. Now get the HTML output (start section row container)
307
- $output = ($wrapper_class) ? "<div class=\"{$wrapper_class}\">" : '';
308
-
309
- // 3. Start fields' section
310
- $output .= ($form_column_class) ? "<div class=\"{$form_column_class}\">" : "";
311
- $output .= "<form method=\"POST\">";
312
-
313
- // Loop through all fields assigned to this section
314
- foreach($fields as $field_name => $field) {
315
- $field['container'] = 'tools';
316
-
317
- // A. Detect fields group
318
- if(isset($field['group'])) {
319
- $output .= "<div class=\"columns-container\">";
320
- // Loop through all fields assigned to this section
321
- foreach($field['group'] as $groupped_field_name => $groupped_field) {
322
- $groupped_field['container'] = 'tools';
323
- $output .= self::generate_option_field($groupped_field_name, $groupped_field);
324
- }
325
- $output .= "</div>";
326
- }
327
- // B. Detect section
328
- else if(isset($field['section_name'])) {
329
- $output .= "<h4>{$field['section_name']}</h4>";
330
- $output .= (isset($section['description'])) ? "<p class=\"description\">{$field['description']}</p>" : "";
331
- $output .= "<table class=\"form-table\">";
332
-
333
- // Loop through all fields assigned to this section
334
- foreach($field['fields'] as $section_field_id => $section_field) {
335
- $section_field_name = "{$field_name}[$section_field_id]";
336
- $section_field['container'] = 'row';
337
-
338
- $output .= self::generate_option_field($section_field_name, $section_field);
339
- }
340
-
341
- $output .= "</table>";
342
- }
343
- // C. Display single field
344
- else {
345
- $output .= self::generate_option_field($field_name, $field);
346
- }
347
- }
348
-
349
- // End the fields' section + add button & nonce fields
350
- $output .= ($nonce_action && $nonce_name) ? wp_nonce_field($nonce_action, $nonce_name, true, true) : "";
351
- $output .= ($button_text) ? get_submit_button($button_text, $button_class, '', false) : "";
352
- $output .= '</form>';
353
- $output .= ($form_column_class) ? "</div>" : "";
354
-
355
- // 4. Display some notes
356
- if($sidebar_class && $sidebar) {
357
- $output .= "<div class=\"{$sidebar_class}\">";
358
- $output .= "<div class=\"section-notes\">";
359
- $output .= $sidebar;
360
- $output .= "</div>";
361
- $output .= "</div>";
362
- }
363
-
364
- // 5. End the section row container
365
- $output .= ($wrapper_class) ? "</div>" : "";
366
-
367
- return $output;
368
- }
369
-
370
- /**
371
- * Display the plugin sections.
372
- */
373
- public function display_section() {
374
- global $wpdb, $permalink_manager_before_sections_html, $permalink_manager_after_sections_html;
375
-
376
- $output = "<div id=\"permalink-manager\" class=\"wrap\">";
377
-
378
- // Display alerts and another content if needed and the plugin header
379
- $output .= $permalink_manager_before_sections_html;
380
- $output .= "<h2 id=\"plugin-name-heading\">" . PERMALINK_MANAGER_PLUGIN_NAME . " <a href=\"" . PERMALINK_MANAGER_WEBSITE ."\" target=\"_blank\">" . __('by Maciej Bis', 'permalink-manager') . "</a></h2>";
381
-
382
- // Display the tab navigation
383
- $output .= "<div id=\"permalink-manager-tab-nav\" class=\"nav-tab-wrapper\">";
384
- foreach($this->sections as $section_name => $section_properties) {
385
- $active_class = ($this->active_section === $section_name) ? 'nav-tab-active nav-tab' : 'nav-tab';
386
- $section_url = $this->get_admin_url("&section={$section_name}");
387
-
388
- $output .= "<a href=\"{$section_url}\" class=\"{$active_class}\">{$section_properties['name']}</a>";
389
- }
390
- $output .= "</div>";
391
-
392
- // Display addidional navigation for subsections
393
- if(isset($this->sections[$this->active_section]['subsections'])) {
394
- $output .= "<ul class=\"subsubsub\">";
395
- foreach ($this->sections[$this->active_section]['subsections'] as $subsection_name => $subsection) {
396
- $active_class = ($this->active_subsection === $subsection_name) ? 'current' : '';
397
- $subsection_url = $this->get_admin_url("&section={$this->active_section}&subsection={$subsection_name}");
398
-
399
- $output .= "<li><a href=\"{$subsection_url}\" class=\"{$active_class}\">{$subsection['name']}</a></li>";
400
- }
401
- $output .= "</ul>";
402
- }
403
-
404
- // Now display the active section
405
- $output .= "<div id=\"permalink-manager-sections\">";
406
- $active_section_array = (isset($this->sections[$this->active_section])) ? $this->sections[$this->active_section] : "";
407
-
408
- // A. Execute the function assigned to the subsection
409
- if(isset($active_section_array['subsections'][$this->active_subsection]['function'])) {
410
- $class_name = $active_section_array['subsections'][$this->active_subsection]['function']['class'];
411
- $section_object = new $class_name();
412
-
413
- $section_content = call_user_func(array($section_object, $active_section_array['subsections'][$this->active_subsection]['function']['method']));
414
- }
415
- // B. Execute the function assigned to the section
416
- else if(isset($active_section_array['function'])) {
417
- $class_name = $active_section_array['function']['class'];
418
- $section_object = new $class_name();
419
-
420
- $section_content = call_user_func(array($section_object, $active_section_array['function']['method']));
421
- }
422
- // C. Display the raw HTMl output
423
- else {
424
- $section_content = (isset($active_section_array['html'])) ? $active_section_array['html'] : "";
425
- }
426
-
427
- $output .= "<div data-section=\"{$this->active_section}\" id=\"{$this->active_section}\">{$section_content}</div>";
428
- $output .= "</div>";
429
-
430
- // Display alerts and another content if needed and close .wrap container
431
- $output .= $permalink_manager_after_sections_html;
432
- $output .= "</div>";
433
-
434
- echo $output;
435
- }
436
-
437
- /**
438
- * Display error/info message
439
- */
440
- static function get_alert_message($alert_content, $alert_type, $dismissable = true) {
441
- $class = ($dismissable) ? "is-dismissible" : "";
442
- $output = sprintf( "<div class=\"{$alert_type} notice {$class}\"> %s</div>", wpautop($alert_content) );
443
-
444
- return $output;
445
- }
446
-
447
- /**
448
- * Display the table with updated slugs after one of the actions is triggered
449
- */
450
- static function display_updated_slugs($updated_array) {
451
- // Check if slugs should be displayed
452
- $first_slug = reset($updated_array);
453
-
454
- $header_footer = '<tr>';
455
- $header_footer .= '<th class="column-primary">' . __('Title', 'permalink-manager') . '</th>';
456
- $header_footer .= '<th>' . __('Old URI', 'permalink-manager') . '</th>';
457
- $header_footer .= '<th>' . __('New URI', 'permalink-manager') . '</th>';
458
- $header_footer .= (isset($first_slug['old_slug'])) ? '<th>' . __('Old Slug', 'permalink-manager') . '</th>' : "";
459
- $header_footer .= (isset($first_slug['new_slug'])) ? '<th>' . __('New Slug', 'permalink-manager') . '</th>' : "";
460
- $header_footer .= '</tr>';
461
-
462
- $updated_slugs_count = 0;
463
- $main_content = "";
464
- foreach($updated_array as $row) {
465
- // Odd/even class
466
- $updated_slugs_count++;
467
- $alternate_class = ($updated_slugs_count % 2 == 1) ? ' class="alternate"' : '';
468
- $permalink = home_url("{$row['new_uri']}");
469
-
470
- $main_content .= "<tr{$alternate_class}>";
471
- $main_content .= '<td class="row-title column-primary" data-colname="' . __('Title', 'permalink-manager') . '">' . $row['post_title'] . "<a target=\"_blank\" href=\"{$permalink}\"><span class=\"small\">{$permalink}</span></a>" . '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __('Show more details', 'permalink-manager') . '</span></button></td>';
472
- $main_content .= '<td data-colname="' . __('Old URI', 'permalink-manager') . '">' . $row['old_uri'] . '</td>';
473
- $main_content .= '<td data-colname="' . __('New URI', 'permalink-manager') . '">' . $row['new_uri'] . '</td>';
474
- $main_content .= (isset($row['old_slug'])) ? '<td data-colname="' . __('Old Slug', 'permalink-manager') . '">' . $row['old_slug'] . '</td>' : "";
475
- $main_content .= (isset($row['new_slug'])) ? '<td data-colname="' . __('New Slug', 'permalink-manager') . '">' . $row['new_slug'] . '</td>' : "";
476
- $main_content .= '</tr>';
477
- }
478
-
479
- // Merge header, footer and content
480
- $output = '<h3 id="updated-list">' . __('List of updated items', 'permalink-manager') . '</h3>';
481
- $output .= '<table class="widefat wp-list-table updated-slugs-table">';
482
- $output .= "<thead>{$header_footer}</thead><tbody>{$main_content}</tbody><tfoot>{$header_footer}</tfoot>";
483
- $output .= '</table>';
484
-
485
- return $output ;
486
- }
487
 
488
  }
1
  <?php
2
 
3
  /**
4
+ * Additional back-end functions related to Wordpress Dashboard UI
5
+ */
6
  class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
7
 
8
+ public $menu_name, $sections, $active_section, $active_subsection;
9
+ public $plugin_slug = PERMALINK_MANAGER_PLUGIN_SLUG;
10
+ public $plugin_basename = PERMALINK_MANAGER_BASENAME;
11
+
12
+ public function __construct() {
13
+ add_action( 'admin_menu', array($this, 'add_menu_page') );
14
+ add_action( 'admin_init', array($this, 'init') );
15
+ }
16
+
17
+ /**
18
+ * Hooks that should be triggered with "admin_init"
19
+ */
20
+ public function init() {
21
+ // Additional link in "Plugins" page
22
+ add_filter( "plugin_action_links_{$this->plugin_basename}", array($this, "plugins_page_links") );
23
+
24
+ // Detect current section
25
+ $this->sections = apply_filters('permalink-manager-sections', array());
26
+ $this->get_current_section();
27
+ }
28
+
29
+ /**
30
+ * Get current section (only in plugin sections)
31
+ */
32
+ public function get_current_section() {
33
+ global $active_section, $active_subsection, $current_admin_tax;
34
+
35
+ // 1. Get current section
36
+ if(isset($_GET['page']) && $_GET['page'] == $this->plugin_slug) {
37
+ if(isset($_POST['section'])) {
38
+ $this->active_section = $_POST['section'];
39
+ } else if(isset($_GET['section'])) {
40
+ $this->active_section = $_GET['section'];
41
+ } else {
42
+ $sections_names = array_keys($this->sections);
43
+ $this->active_section = $sections_names[0];
44
+ }
45
+ }
46
+
47
+ // 2. Get current subsection
48
+ if($this->active_section && isset($this->sections[$this->active_section]['subsections'])) {
49
+ if(isset($_POST['subsection'])) {
50
+ $this->active_subsection = $_POST['subsection'];
51
+ } else if(isset($_GET['subsection'])) {
52
+ $this->active_subsection = $_GET['subsection'];
53
+ } else {
54
+ $subsections_names = array_keys($this->sections[$this->active_section]['subsections']);
55
+ $this->active_subsection = $subsections_names[0];
56
+ }
57
+ }
58
+
59
+ // Check if current admin page is related to taxonomies
60
+ if(substr($this->active_subsection, 0, 4) == 'tax_') {
61
+ $current_admin_tax = substr($this->active_subsection, 4, strlen($this->active_subsection));
62
+ } else {
63
+ $current_admin_tax = false;
64
+ }
65
+
66
+ // Set globals
67
+ $active_section = $this->active_section;
68
+ $active_subsection = $this->active_subsection;
69
+ }
70
+
71
+ /**
72
+ * Add menu page.
73
+ */
74
+ public function add_menu_page() {
75
+ $this->menu_name = add_management_page( __('Permalink Manager', 'permalink-manager'), __('Permalink Manager', 'permalink-manager'), 'manage_options', $this->plugin_slug, array($this, 'display_section') );
76
+
77
+ // Make sure thata the CSS and JS files are loaded only on plugin admin page.
78
+ add_action( 'admin_print_styles-' . $this->menu_name, array($this, 'enqueue_styles' ) );
79
+ add_action( 'admin_print_scripts-' . $this->menu_name, array($this, 'enqueue_scripts' ) );
80
+ }
81
+
82
+ /**
83
+ * Register the CSS file for the dashboard.
84
+ */
85
+ public function enqueue_styles() {
86
+ wp_enqueue_style( $this->plugin_slug, PERMALINK_MANAGER_URL . '/out/permalink-manager-admin.css', array(), PERMALINK_MANAGER_VERSION, 'all' );
87
+ }
88
+
89
+ /**
90
+ * Register the JavaScript file for the dashboard.
91
+ */
92
+ public function enqueue_scripts() {
93
+ wp_enqueue_script( $this->plugin_slug, PERMALINK_MANAGER_URL . '/out/permalink-manager-admin.js', array( 'jquery' ), PERMALINK_MANAGER_VERSION, false );
94
+ }
95
+
96
+ /**
97
+ * Get admin url for the plugin
98
+ */
99
+ function get_admin_url($append = '') {
100
+ return menu_page_url( "{$this->plugin_slug}", false ) . $append;
101
+ }
102
+
103
+ /**
104
+ * Additional links on "Plugins" page
105
+ */
106
+ public function plugins_page_links($links) {
107
+ $links[] = '<a href="' . $this->get_admin_url() .'">' . __( 'Go To Permalink Manager', 'permalink-manager' ) . '</a>';
108
+ return $links;
109
+ }
110
+
111
+ /**
112
+ * Generate the fields
113
+ */
114
+ static public function generate_option_field($input_name, $args) {
115
+ global $permalink_manager_options;
116
+
117
+ // Reset $fields variables
118
+ $fields = $section_name = $field_name = '';
119
+
120
+ // Allow to filter the $args
121
+ $args = apply_filters('permalink-manager-field-args', $args, $input_name);
122
+
123
+ $default = (isset($args['default'])) ? $args['default'] : '';
124
+ $label = (isset($args['label'])) ? $args['label'] : '';
125
+ $placeholder = (isset($args['placeholder'])) ? "placeholder=\"{$args['placeholder']}\"" : '';
126
+ $readonly = (isset($args['readonly'])) ? "readonly=\"readonly\"" : '';
127
+ $rows = (isset($args['rows'])) ? "rows=\"{$rows}\"" : "rows=\"5\"";
128
+ $input_class = (isset($args['input_class'])) ? "class=\"{$args['input_class']}\"" : '';
129
+ $container_class = (isset($args['container_class'])) ? " class=\"{$args['container_class']} field-container\"" : " class=\"field-container\"";
130
+ $description = (isset($args['description'])) ? "<p class=\"field-description description\">{$args['description']}</p>" : "";
131
+ $append_content = (isset($args['append_content'])) ? "{$args['append_content']}" : "";
132
+
133
+ // Get the field value (if it is not set in $args)
134
+ if(isset($args['value']) && empty($args['value']) == false) {
135
+ $value = $args['value'];
136
+ } else {
137
+ // Extract the section and field name from $input_name
138
+ preg_match("/(.*)\[(.*)\]/", $input_name, $field_section_and_name);
139
+
140
+ if($field_section_and_name) {
141
+ $section_name = $field_section_and_name[1];
142
+ $field_name = $field_section_and_name[2];
143
+ $value = (isset($permalink_manager_options[$section_name][$field_name])) ? $permalink_manager_options[$section_name][$field_name] : $default;
144
+ } else {
145
+ $value = (isset($permalink_manager_options[$input_name])) ? $permalink_manager_options[$input_name] : $default;
146
+ }
147
+ }
148
+
149
+ switch($args['type']) {
150
+ case 'checkbox' :
151
+ $fields .= '<div class="checkboxes">';
152
+ foreach($args['choices'] as $choice_value => $checkbox_label) {
153
+ $checked = (is_array($value) && in_array($choice_value, $value)) ? "checked='checked'" : "";
154
+ $fields .= "<label for='{$input_name}[]'><input type='checkbox' {$input_class} value='{$choice_value}' name='{$input_name}[]' {$checked} /> {$checkbox_label}</label>";
155
+ }
156
+ $fields .= '</div>';
157
+
158
+ // Add helper checkboxes for bulk actions
159
+ if(isset($args['select_all']) || isset($args['unselect_all'])) {
160
+ $select_all_label = (!empty($args['select_all'])) ? $args['select_all'] : __('Select all', 'permalink-manager');
161
+ $unselect_all_label = (!empty($args['unselect_all'])) ? $args['unselect_all'] : __('Unselect all', 'permalink-manager');
162
+
163
+ $fields .= "<p class=\"checkbox_actions extra-links\">";
164
+ $fields .= (isset($args['select_all'])) ? "<a href=\"#\" class=\"select_all\">{$select_all_label}</a>&nbsp;" : "";
165
+ $fields .= (isset($args['unselect_all'])) ? "<a href=\"#\" class=\"unselect_all\">{$unselect_all_label}</a>" : "";
166
+ $fields .= "</p>";
167
+ }
168
+ break;
169
+
170
+ case 'radio' :
171
+ $fields .= '<div class="radios">';
172
+ foreach($args['choices'] as $choice_value => $checkbox_label) {
173
+ $checked = ($choice_value == $value) ? "checked='checked'" : "";
174
+ $fields .= "<label for='{$input_name}[]'><input type='radio' {$input_class} value='{$choice_value}' name='{$input_name}[]' {$checked} /> {$checkbox_label}</label>";
175
+ }
176
+ $fields .= '</div>';
177
+ break;
178
+
179
+ case 'select' :
180
+ $fields .= '<div class="select">';
181
+ $fields .= "<select name='{$input_name}' {$input_class}>";
182
+ foreach($args['choices'] as $choice_value => $checkbox_label) {
183
+ $selected = ($choice_value == $value) ? "selected='selected'" : "";
184
+ $fields .= "<option value='{$choice_value}' {$selected} />{$checkbox_label}</option>";
185
+ }
186
+ $fields .= '</select>';
187
+ $fields .= '</div>';
188
+ break;
189
+
190
+ case 'number' :
191
+ $fields .= "<input type='number' {$input_class} value='{$value}' name='{$input_name}' />";
192
+ break;
193
+
194
+ case 'hidden' :
195
+ $fields .= "<input type='hidden' {$input_class} value='{$value}' name='{$input_name}' />";
196
+ break;
197
+
198
+ case 'textarea' :
199
+ $fields .= "<textarea {$input_class} name='{$input_name}' {$placeholder} {$readonly} {$rows}>{$value}</textarea>";
200
+ break;
201
+
202
+ case 'pre' :
203
+ $fields .= "<pre {$input_class}>{$value}</pre>";
204
+ break;
205
+
206
+ case 'clearfix' :
207
+ return "<div class=\"clearfix\"></div>";
208
+
209
+ case 'permastruct' :
210
+ $siteurl = get_bloginfo('wpurl');
211
+ $fields .= "<code>{$siteurl}/</code><input type='text' {$input_class} value='{$value}' name='{$input_name}' {$placeholder} {$readonly}/>";
212
+ break;
213
+
214
+ default :
215
+ $fields .= "<input type='text' {$input_class} value='{$value}' name='{$input_name}' {$placeholder} {$readonly}/>";
216
+ }
217
+
218
+ // Get the final HTML output
219
+ if(isset($args['container']) && $args['container'] == 'tools') {
220
+ $output = "<div{$container_class}>";
221
+ $output .= "<h4>{$label}</h4>";
222
+ $output .= "<div class='{$input_name}-container'>{$fields}</div>";
223
+ $output .= $description;
224
+ $output .= $append_content;
225
+ $output .= "</div>";
226
+ } else if(isset($args['container']) && $args['container'] == 'row') {
227
+ $output = "<tr><th><label for='{$input_name}'>{$args['label']}</label></th>";
228
+ $output .= "<td>{$fields}{$description}</td></tr>";
229
+ $output .= ($append_content) ? "<tr class=\"appended-row\"><td colspan=\"2\">{$append_content}</td></tr>" : "";
230
+ } else {
231
+ $output = $fields . $append_content;
232
+ }
233
+
234
+ return apply_filters('permalink-manager-field-output', $output);
235
+ }
236
+
237
+ /**
238
+ * Display hidden field to indicate posts or taxonomies admin sections
239
+ */
240
+ static public function section_type_field($type = 'post') {
241
+ return self::generate_option_field('section_type', array('value' => $type, 'type' => 'hidden'));
242
+ }
243
+
244
+ /**
245
+ * Display the form
246
+ */
247
+ static public function get_the_form($fields = array(), $container = '', $button = array(), $sidebar = '', $nonce = array()) {
248
+ // 1. Check if the content will be displayed in columns and button details
249
+ switch($container) {
250
+ case 'columns-3' :
251
+ $wrapper_class = 'columns-container';
252
+ $form_column_class = 'column column-2_3';
253
+ $sidebar_class = 'column column-1_3';
254
+ break;
255
+ // there will be more cases in future ...
256
+ default :
257
+ $form_column_class = 'form';
258
+ $sidebar_class = 'sidebar';
259
+ $wrapper_class = $form_column_class = '';
260
+ }
261
+
262
+ // 2. Process the array with button and nonce field settings
263
+ $button_text = (!empty($button['text'])) ? $button['text'] : '';
264
+ $button_class = (!empty($button['class'])) ? $button['class'] : '';
265
+ $nonce_action = (!empty($nonce['action'])) ? $nonce['action'] : '';
266
+ $nonce_name = (!empty($nonce['name'])) ? $nonce['name'] : '';
267
+
268
+ // 2. Now get the HTML output (start section row container)
269
+ $output = ($wrapper_class) ? "<div class=\"{$wrapper_class}\">" : '';
270
+
271
+ // 3. Display some notes
272
+ if($sidebar_class && $sidebar) {
273
+ $output .= "<div class=\"{$sidebar_class}\">";
274
+ $output .= "<div class=\"section-notes\">";
275
+ $output .= $sidebar;
276
+ $output .= "</div>";
277
+ $output .= "</div>";
278
+ }
279
+
280
+ // 4. Start fields' section
281
+ $output .= ($form_column_class) ? "<div class=\"{$form_column_class}\">" : "";
282
+ $output .= "<form method=\"POST\">";
283
+
284
+ // Loop through all fields assigned to this section
285
+ foreach($fields as $field_name => $field) {
286
+ $field_name = (!empty($field['name'])) ? $field['name'] : $field_name;
287
+
288
+ // A. Display table row
289
+ if(isset($field['container']) && $field['container'] == 'row') {
290
+ $output .= (isset($field['section_name'])) ? "<h3>{$field['section_name']}</h3>" : "";
291
+ $output .= (isset($field['description'])) ? "<p class=\"description\">{$field['description']}</p>" : "";
292
+ $output .= (isset($field['append_content'])) ? $field['append_content'] : "";
293
+ $output .= "<table class=\"form-table\">";
294
+
295
+ // Loop through all fields assigned to this section
296
+ if(isset($field['fields'])) {
297
+ foreach($field['fields'] as $section_field_id => $section_field) {
298
+ $section_field_name = (!empty($section_field['name'])) ? $section_field['name'] : "{$field_name}[$section_field_id]";
299
+ $section_field['container'] = 'row';
300
+
301
+ $output .= self::generate_option_field($section_field_name, $section_field);
302
+ }
303
+ } else {
304
+ $output .= self::generate_option_field($field_name, $field);
305
+ }
306
+
307
+ $output .= "</table>";
308
+ }
309
+ // B. Display single field
310
+ else {
311
+ $output .= self::generate_option_field($field_name, $field);
312
+ }
313
+ }
314
+
315
+ // End the fields' section + add button & nonce fields
316
+ $output .= ($nonce_action && $nonce_name) ? wp_nonce_field($nonce_action, $nonce_name, true, true) : "";
317
+ $output .= ($button_text) ? get_submit_button($button_text, $button_class, '', false) : "";
318
+ $output .= '</form>';
319
+ $output .= ($form_column_class) ? "</div>" : "";
320
+
321
+ // 5. End the section row container
322
+ $output .= ($wrapper_class) ? "</div>" : "";
323
+
324
+ return $output;
325
+ }
326
+
327
+ /**
328
+ * Display the plugin sections.
329
+ */
330
+ public function display_section() {
331
+ global $wpdb, $permalink_manager_before_sections_html, $permalink_manager_after_sections_html;
332
+
333
+ $output = "<div id=\"permalink-manager\" class=\"wrap\">";
334
+
335
+ // Display alerts and another content if needed and the plugin header
336
+ $output .= $permalink_manager_before_sections_html;
337
+ $output .= "<h2 id=\"plugin-name-heading\">" . PERMALINK_MANAGER_PLUGIN_NAME . " <a href=\"" . PERMALINK_MANAGER_WEBSITE ."\" target=\"_blank\">" . __('by Maciej Bis', 'permalink-manager') . "</a></h2>";
338
+
339
+ // Display the tab navigation
340
+ $output .= "<div id=\"permalink-manager-tab-nav\" class=\"nav-tab-wrapper\">";
341
+ foreach($this->sections as $section_name => $section_properties) {
342
+ $active_class = ($this->active_section === $section_name) ? 'nav-tab-active nav-tab' : 'nav-tab';
343
+ $section_url = $this->get_admin_url("&section={$section_name}");
344
+
345
+ $output .= "<a href=\"{$section_url}\" class=\"{$active_class}\">{$section_properties['name']}</a>";
346
+ }
347
+ $output .= "</div>";
348
+
349
+ // Now display the active section
350
+ $output .= "<div id=\"permalink-manager-sections\">";
351
+ $active_section_array = (isset($this->sections[$this->active_section])) ? $this->sections[$this->active_section] : "";
352
+
353
+ // Display addidional navigation for subsections
354
+ if(isset($this->sections[$this->active_section]['subsections'])) {
355
+ $output .= "<ul class=\"subsubsub\">";
356
+ foreach ($this->sections[$this->active_section]['subsections'] as $subsection_name => $subsection) {
357
+ $active_class = ($this->active_subsection === $subsection_name) ? 'current' : '';
358
+ $subsection_url = $this->get_admin_url("&section={$this->active_section}&subsection={$subsection_name}");
359
+
360
+ $output .= "<li><a href=\"{$subsection_url}\" class=\"{$active_class}\">{$subsection['name']}</a></li>";
361
+ }
362
+ $output .= "</ul>";
363
+ }
364
+
365
+ // A. Execute the function assigned to the subsection
366
+ if(isset($active_section_array['subsections'][$this->active_subsection]['function'])) {
367
+ $class_name = $active_section_array['subsections'][$this->active_subsection]['function']['class'];
368
+ $section_object = new $class_name();
369
+
370
+ $section_content = call_user_func(array($section_object, $active_section_array['subsections'][$this->active_subsection]['function']['method']));
371
+ }
372
+ // B. Execute the function assigned to the section
373
+ else if(isset($active_section_array['function'])) {
374
+ $class_name = $active_section_array['function']['class'];
375
+ $section_object = new $class_name();
376
+
377
+ $section_content = call_user_func(array($section_object, $active_section_array['function']['method']));
378
+ }
379
+ // C. Display the raw HTMl output of subsection
380
+ else if(isset($active_section_array['subsections'][$this->active_subsection]['html'])) {
381
+ $section_content = (isset($active_section_array['subsections'][$this->active_subsection]['html'])) ? $active_section_array['subsections'][$this->active_subsection]['html'] : "";
382
+ }
383
+ // D. Try to display the raw HTMl output of section
384
+ else {
385
+ $section_content = (isset($active_section_array['html'])) ? $active_section_array['html'] : "";
386
+ }
387
+
388
+ $output .= "<div data-section=\"{$this->active_section}\" id=\"{$this->active_section}\">{$section_content}</div>";
389
+ $output .= "</div>";
390
+
391
+ // Display alerts and another content if needed and close .wrap container
392
+ $output .= $permalink_manager_after_sections_html;
393
+ $output .= "</div>";
394
+
395
+ echo $output;
396
+ }
397
+
398
+ /**
399
+ * Display error/info message
400
+ */
401
+ public static function get_alert_message($alert_content, $alert_type, $dismissable = true) {
402
+ $class = ($dismissable) ? "is-dismissible" : "";
403
+ $output = sprintf( "<div class=\"{$alert_type} notice {$class}\"> %s</div>", wpautop($alert_content) );
404
+
405
+ return $output;
406
+ }
407
+
408
+ static function pro_text() {
409
+ $output = sprintf( "<div class=\"alert info\"> %s</div>", wpautop(__('This functionality is available only in "Permalink Manager Pro".'), 'alert', false) );
410
+ return $output;
411
+ }
412
+
413
+ /**
414
+ * Display the table with updated slugs after one of the actions is triggered
415
+ */
416
+ static function display_updated_slugs($updated_array, $uri_type = 'post') {
417
+ // Check if slugs should be displayed
418
+ $first_slug = reset($updated_array);
419
+
420
+ $header_footer = '<tr>';
421
+ $header_footer .= '<th class="column-primary">' . __('Title', 'permalink-manager') . '</th>';
422
+ $header_footer .= '<th>' . __('Old URI', 'permalink-manager') . '</th>';
423
+ $header_footer .= '<th>' . __('New URI', 'permalink-manager') . '</th>';
424
+ $header_footer .= (isset($first_slug['old_slug'])) ? '<th>' . __('Old Slug', 'permalink-manager') . '</th>' : "";
425
+ $header_footer .= (isset($first_slug['new_slug'])) ? '<th>' . __('New Slug', 'permalink-manager') . '</th>' : "";
426
+ $header_footer .= '</tr>';
427
+
428
+ $updated_slugs_count = 0;
429
+ $main_content = "";
430
+ foreach($updated_array as $row) {
431
+ // Odd/even class
432
+ $updated_slugs_count++;
433
+ $alternate_class = ($updated_slugs_count % 2 == 1) ? ' class="alternate"' : '';
434
+ $permalink = get_permalink($row['ID']);
435
+
436
+ $main_content .= "<tr{$alternate_class}>";
437
+ $main_content .= '<td class="row-title column-primary" data-colname="' . __('Title', 'permalink-manager') . '">' . $row['post_title'] . "<a target=\"_blank\" href=\"{$permalink}\"><span class=\"small\">{$permalink}</span></a>" . '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __('Show more details', 'permalink-manager') . '</span></button></td>';
438
+ $main_content .= '<td data-colname="' . __('Old URI', 'permalink-manager') . '">' . $row['old_uri'] . '</td>';
439
+ $main_content .= '<td data-colname="' . __('New URI', 'permalink-manager') . '">' . $row['new_uri'] . '</td>';
440
+ $main_content .= (isset($row['old_slug'])) ? '<td data-colname="' . __('Old Slug', 'permalink-manager') . '">' . $row['old_slug'] . '</td>' : "";
441
+ $main_content .= (isset($row['new_slug'])) ? '<td data-colname="' . __('New Slug', 'permalink-manager') . '">' . $row['new_slug'] . '</td>' : "";
442
+ $main_content .= '</tr>';
443
+ }
444
+
445
+ // Merge header, footer and content
446
+ $output = '<h3 id="updated-list">' . __('List of updated items', 'permalink-manager') . '</h3>';
447
+ $output .= '<table class="widefat wp-list-table updated-slugs-table">';
448
+ $output .= "<thead>{$header_footer}</thead><tbody>{$main_content}</tbody><tfoot>{$header_footer}</tfoot>";
449
+ $output .= '</table>';
450
+
451
+ return $output;
452
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
453
 
454
  }
includes/core/permalink-manager-helper-functions.php CHANGED
@@ -1,115 +1,150 @@
1
  <?php
2
 
3
  /**
4
- * Additional functions used in classes and another subclasses
5
- */
6
  class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
7
 
8
- public function __construct() { }
9
-
10
- /**
11
- * Support for multidimensional arrays - array_map()
12
- */
13
- static function multidimensional_array_map($function, $input) {
14
- $output = array();
15
-
16
- if(is_array($input)) {
17
- foreach ($input as $key => $val) {
18
- $output[$key] = (is_array($val) ? self::multidimensional_array_map($function, $val) : $function($val));
19
- }
20
- } else {
21
- $output = $function($input);
22
- }
23
-
24
- return $output;
25
- }
26
-
27
- /**
28
- * Get primary term (by Yoast SEO)
29
- */
30
- static function get_primary_term($post_id, $taxonomy) {
31
- global $permalink_manager_options;
32
-
33
- if($permalink_manager_options['miscellaneous']['yoast_primary_term'] == 1 && class_exists('WPSEO_Primary_Term')) {
34
- $primary_term = new WPSEO_Primary_Term($taxonomy, $post_id);
35
- $primary_term = get_term($primary_term->get_primary_term());
36
- return (!is_wp_error($primary_term)) ? $primary_term->slug : "";
37
- } else {
38
- return '';
39
- }
40
- }
41
 
42
  /**
43
- * Get post_types array
44
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  static function get_post_types_array($format = null, $cpt = null) {
46
- $post_types = apply_filters('permalink-manager-post-types', get_post_types( array('public' => true), 'objects'));
47
-
48
- $post_types_array = array();
49
- if($format == 'full') {
50
- foreach ( $post_types as $post_type ) {
51
- $post_types_array[$post_type->name] = array('label' => $post_type->labels->name, 'name' => $post_type->name);
52
- }
53
- } else {
54
- foreach ( $post_types as $post_type ) {
55
- $post_types_array[$post_type->name] = $post_type->labels->name;
56
- }
57
- }
58
-
59
- return (empty($cpt)) ? $post_types_array : $post_types_array[$cpt];
60
- }
61
-
62
- /**
63
- * Get permastruct
64
- */
65
- static function get_default_permastruct($post_type = 'page', $remove_post_tag = false) {
66
- global $wp_rewrite;
67
-
68
- // Get default permastruct
69
- if($post_type == 'page') {
70
- $permastruct = $wp_rewrite->get_page_permastruct();
71
- } else if($post_type == 'post') {
72
- $permastruct = get_option('permalink_structure');
73
- } else {
74
- $permastruct = $wp_rewrite->get_extra_permastruct($post_type);
75
- }
76
-
77
- return ($remove_post_tag) ? trim(str_replace(array("%postname%", "%pagename%", "%{$post_type}%"), "", $permastruct), "/") : $permastruct;
78
- }
79
-
80
- /**
81
- * Structure Tags & Rewrite functions
82
- */
83
- static function get_all_structure_tags($code = true, $seperator = ', ', $hide_slug_tags = true) {
84
- global $wp_rewrite;
85
-
86
- $tags = $wp_rewrite->rewritecode;
87
- $output = "";
88
- $last_tag_index = count($tags);
89
- $i = 1;
90
-
91
- // Hide slug tags
92
- if($hide_slug_tags) {
93
- $post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
94
- foreach($post_types as $post_type => $post_type_name) {
95
- $post_type_tag = Permalink_Manager_Helper_Functions::get_post_tag($post_type);
96
- // Find key with post type tag from rewritecode
97
- $key = array_search($post_type_tag, $tags);
98
- if($key) { unset($tags[$key]); }
99
- }
100
- }
101
-
102
- foreach($tags as $tag) {
103
- $sep = ($last_tag_index == $i) ? "" : $seperator;
104
- $output .= ($code) ? "<code>{$tag}</code>{$sep}" : "{$tag}{$sep}";
105
- $i++;
106
- }
107
-
108
- return $output;
109
- }
110
-
111
- static function get_post_tag($post_type) {
112
- // Get the post type (with fix for posts & pages)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  if($post_type == 'page') {
114
  $post_type_tag = '%pagename%';
115
  } else if ($post_type == 'post') {
@@ -117,7 +152,15 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
117
  } else {
118
  $post_type_tag = "%{$post_type}%";
119
  }
120
- return $post_type_tag;
121
- }
 
 
 
 
 
 
 
 
122
 
123
  }
1
  <?php
2
 
3
  /**
4
+ * Additional functions used in classes and another subclasses
5
+ */
6
  class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
7
 
8
+ public function __construct() { }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  /**
11
+ * Support for multidimensional arrays - array_map()
12
+ */
13
+ static function multidimensional_array_map($function, $input) {
14
+ $output = array();
15
+
16
+ if(is_array($input)) {
17
+ foreach ($input as $key => $val) {
18
+ $output[$key] = (is_array($val) ? self::multidimensional_array_map($function, $val) : $function($val));
19
+ }
20
+ } else {
21
+ $output = $function($input);
22
+ }
23
+
24
+ return $output;
25
+ }
26
+
27
+ /**
28
+ * Get primary term (by Yoast SEO)
29
+ */
30
+ static function get_primary_term($post_id, $taxonomy) {
31
+ global $permalink_manager_options;
32
+
33
+ if($permalink_manager_options['miscellaneous']['yoast_primary_term'] == 1 && class_exists('WPSEO_Primary_Term')) {
34
+ $primary_term = new WPSEO_Primary_Term($taxonomy, $post_id);
35
+ $primary_term = get_term($primary_term->get_primary_term());
36
+ return (!is_wp_error($primary_term)) ? $primary_term->slug : "";
37
+ } else {
38
+ return '';
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Get post_types array
44
+ */
45
  static function get_post_types_array($format = null, $cpt = null) {
46
+ $post_types = apply_filters('permalink-manager-post-types', get_post_types( array('public' => true), 'objects'));
47
+
48
+ $post_types_array = array();
49
+ if($format == 'full') {
50
+ foreach ( $post_types as $post_type ) {
51
+ $post_types_array[$post_type->name] = array('label' => $post_type->labels->name, 'name' => $post_type->name);
52
+ }
53
+ } else {
54
+ foreach ( $post_types as $post_type ) {
55
+ $post_types_array[$post_type->name] = $post_type->labels->name;
56
+ }
57
+ }
58
+
59
+ return (empty($cpt)) ? $post_types_array : $post_types_array[$cpt];
60
+ }
61
+
62
+ /**
63
+ * Get array with all taxonomies
64
+ */
65
+ static function get_taxonomies_array($format = null, $tax = null) {
66
+ $taxonomies = apply_filters('permalink-manager-taxonomies', get_taxonomies(array('public' => true, 'rewrite' => true), 'objects'));
67
+
68
+ $taxonomies_array = array();
69
+ if($format == 'full') {
70
+ foreach ( $taxonomies as $taxonomy ) {
71
+ $taxonomies_array[$taxonomy->name] = array('label' => $taxonomy->labels->name, 'name' => $taxonomy->name);
72
+ }
73
+ } else {
74
+ foreach ( $taxonomies as $taxonomy ) {
75
+ $taxonomies_array[$taxonomy->name] = $taxonomy->labels->name;
76
+ }
77
+ }
78
+
79
+ return (empty($tax)) ? $taxonomies_array : $taxonomies_array[$tax];
80
+ }
81
+
82
+ /**
83
+ * Get permastruct
84
+ */
85
+ static function get_default_permastruct($post_type = 'page', $remove_post_tag = false) {
86
+ global $wp_rewrite;
87
+
88
+ // Get default permastruct
89
+ if($post_type == 'page') {
90
+ $permastruct = $wp_rewrite->get_page_permastruct();
91
+ } else if($post_type == 'post') {
92
+ $permastruct = get_option('permalink_structure');
93
+ } else {
94
+ $permastruct = $wp_rewrite->get_extra_permastruct($post_type);
95
+ }
96
+
97
+ return ($remove_post_tag) ? trim(str_replace(array("%postname%", "%pagename%", "%{$post_type}%"), "", $permastruct), "/") : $permastruct;
98
+ }
99
+
100
+ /**
101
+ * Remove post tag from permastructure
102
+ */
103
+ static function remove_post_tag($permastruct) {
104
+ $post_types = self::get_post_types_array('full');
105
+
106
+ // Get all post tags
107
+ $post_tags = array("%postname%", "%pagename%");
108
+ foreach($post_types as $post_type) {
109
+ $post_tags[] = "%{$post_type['name']}%";
110
+ }
111
+
112
+ $permastruct = str_replace($post_tags, "", $permastruct);
113
+ return trim($permastruct, "/");
114
+ }
115
+
116
+ /**
117
+ * Structure Tags & Rewrite functions
118
+ */
119
+ static function get_all_structure_tags($code = true, $seperator = ', ', $hide_slug_tags = true) {
120
+ global $wp_rewrite;
121
+
122
+ $tags = $wp_rewrite->rewritecode;
123
+
124
+ // Hide slug tags
125
+ if($hide_slug_tags) {
126
+ $post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
127
+ foreach($post_types as $post_type => $post_type_name) {
128
+ $post_type_tag = Permalink_Manager_Helper_Functions::get_post_tag($post_type);
129
+ // Find key with post type tag from rewritecode
130
+ $key = array_search($post_type_tag, $tags);
131
+ if($key) { unset($tags[$key]); }
132
+ }
133
+ }
134
+
135
+ foreach($tags as &$tag) {
136
+ $tag = ($code) ? "<code>{$tag}</code>" : "{$tag}";
137
+ }
138
+ $output = implode($seperator, $tags);
139
+
140
+ return "<span class=\"structure-tags-list\">{$output}</span>";
141
+ }
142
+
143
+ /**
144
+ * Get endpoint used to mark the postname or its equivalent for custom post types and pages in permastructures
145
+ */
146
+ static function get_post_tag($post_type) {
147
+ // Get the post type (with fix for posts & pages)
148
  if($post_type == 'page') {
149
  $post_type_tag = '%pagename%';
150
  } else if ($post_type == 'post') {
152
  } else {
153
  $post_type_tag = "%{$post_type}%";
154
  }
155
+ return $post_type_tag;
156
+ }
157
+
158
+ /**
159
+ * Find taxonomy name using "term_id"
160
+ */
161
+ static function get_tax_name($term, $term_by = 'id') {
162
+ $term_object = get_term_by($term_by, $term);
163
+ return (isset($term_object->taxonomy)) ? $term_object->taxonomy : '';
164
+ }
165
 
166
  }
includes/core/permalink-manager-post-uri-functions.php DELETED
@@ -1,445 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Additional functions used in classes and another subclasses
5
- */
6
- class Permalink_Manager_Post_URI_Functions extends Permalink_Manager_Class {
7
-
8
- public function __construct() {
9
- add_filter( '_get_page_link', array($this, 'custom_post_permalinks'), 999, 2);
10
- add_filter( 'page_link', array($this, 'custom_post_permalinks'), 999, 2);
11
- add_filter( 'post_link', array($this, 'custom_post_permalinks'), 999, 2);
12
- add_filter( 'post_type_link', array($this, 'custom_post_permalinks'), 999, 2);
13
- add_filter( 'permalink-manager-uris', array($this, 'exclude_homepage'), 999, 2);
14
- add_action( 'save_post', array($this, 'update_post_uri'), 10, 3 );
15
- add_action( 'wp_trash_post', array($this, 'remove_post_uri'), 10, 3 );
16
- }
17
-
18
- /**
19
- * Change permalinks for posts, pages & custom post types
20
- */
21
- function custom_post_permalinks($permalink, $post) {
22
- global $wp_rewrite, $permalink_manager_uris;
23
-
24
- $post = (is_integer($post)) ? get_post($post) : $post;
25
- $post_type = $post->post_type;
26
-
27
- // Do not change permalink of frontpage
28
- if(get_option('page_on_front') == $post->ID) { return $permalink; }
29
- if(isset($permalink_manager_uris[$post->ID])) $permalink = home_url('/') . $permalink_manager_uris[$post->ID];
30
-
31
- return $permalink;
32
- }
33
-
34
- /**
35
- * Display the permalink in a better way
36
- */
37
- static function get_correct_permalink($id) {
38
- global $permalink_manager_uris;
39
- $permalink = isset($permalink_manager_uris[$id]) ? home_url('/') . $permalink_manager_uris[$id] : get_permalink($id);
40
-
41
- return $permalink;
42
- }
43
-
44
- /**
45
- * Check if the provided slug is unique and then update it with SQL query.
46
- */
47
- static function update_slug_by_id($slug, $id) {
48
- global $wpdb;
49
-
50
- // Update slug and make it unique
51
- $slug = (empty($slug)) ? sanitize_title(get_the_title($id)) : $slug;
52
- $new_slug = wp_unique_post_slug($slug, $id, get_post_status($id), get_post_type($id), null);
53
- $wpdb->query("UPDATE $wpdb->posts SET post_name = '$new_slug' WHERE ID = '$id'");
54
-
55
- return $new_slug;
56
- }
57
-
58
- /**
59
- * Get the active URI
60
- */
61
- static function get_post_uri($post_id) {
62
- global $permalink_manager_uris;
63
-
64
- // Check if input is post object
65
- $post_id = (isset($post_id->ID)) ? $post_id->ID : $post_id;
66
-
67
- $final_uri = isset($permalink_manager_uris[$post_id]) ? $permalink_manager_uris[$post_id] : self::get_default_post_uri($post_id);
68
- return $final_uri;
69
- }
70
-
71
- /**
72
- * Get the default (not overwritten by the user) or native URI (unfiltered)
73
- */
74
- static function get_default_post_uri($post, $native_uri = false) {
75
- global $permalink_manager_options, $permalink_manager_uris, $permalink_manager_permastructs;
76
-
77
- // Load all bases & post
78
- $post = is_object($post) ? $post : get_post($post);
79
- $post_id = $post->ID;
80
- $post_type = $post->post_type;
81
- $post_name = $post->post_name;
82
-
83
- // Get the permastruct
84
- $default_permastruct = Permalink_Manager_Helper_Functions::get_default_permastruct($post_type);
85
-
86
- if($native_uri) {
87
- $permastruct = $default_permastruct;
88
- } else if($permalink_manager_permastructs) {
89
- $permastruct = isset($permalink_manager_permastructs[$post_type]) ? $permalink_manager_permastructs[$post_type] : $default_permastruct;
90
- } else {
91
- $permastruct = isset($permalink_manager_options['base-editor'][$post_type]) ? $permalink_manager_options['base-editor'][$post_type] : $default_permastruct;
92
- }
93
- $default_base = (!empty($permastruct)) ? trim($permastruct, '/') : "";
94
-
95
- // 1A. Get the date
96
- $date = explode(" ",date('Y m d H i s', strtotime($post->post_date)));
97
-
98
- // 1B. Get the category slug (if needed)
99
- $category = '';
100
- if ( strpos($default_base, '%category%') !== false ) {
101
-
102
- // I. Try to use Yoast SEO Primary Term
103
- $category = (Permalink_Manager_Helper_Functions::get_primary_term($post->ID, 'category'));
104
-
105
- // II. Get the first assigned category
106
- if(empty($category)) {
107
- $cats = get_the_category($post->ID);
108
- if ($cats) {
109
- usort($cats, '_usort_terms_by_ID'); // order by ID
110
- $category_object = apply_filters( 'post_link_category', $cats[0], $cats, $post );
111
- $category_object = get_term( $category_object, 'category' );
112
- $category = $category_object->slug;
113
- if ( $parent = $category_object->parent )
114
- $category = get_category_parents($parent, false, '/', true) . $category;
115
- }
116
- }
117
-
118
- // III. Show default category in permalinks, without having to assign it explicitly
119
- if(empty($category)) {
120
- $default_category = get_term( get_option( 'default_category' ), 'category' );
121
- $category = is_wp_error( $default_category ) ? '' : $default_category->slug;
122
- }
123
- }
124
-
125
- // 1C. Get the author (if needed)
126
- $author = '';
127
- if ( strpos($default_base, '%author%') !== false ) {
128
- $authordata = get_userdata($post->post_author);
129
- $author = $authordata->user_nicename;
130
- }
131
-
132
- // 2. Fix for hierarchical CPT (start)
133
- $full_slug = get_page_uri($post);
134
- $post_type_tag = Permalink_Manager_Helper_Functions::get_post_tag($post_type);
135
-
136
- // 3A. Do the replacement (post tag is removed now to enable support for hierarchical CPT)
137
- $tags = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', '%post_id%', '%category%', '%author%', $post_type_tag);
138
- $replacements = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->ID, $category, $author, '');
139
- $default_uri = str_replace($tags, $replacements, "{$default_base}/{$full_slug}");
140
-
141
- // 3B. Replace custom taxonomies
142
- $terms = get_taxonomies( array('public' => true, '_builtin' => false), 'names', 'and' );
143
- $taxonomies = $terms;
144
- if ( $taxonomies ) {
145
- foreach($taxonomies as $taxonomy) {
146
- // A. Try to use Yoast SEO Primary Term
147
- $category = (Permalink_Manager_Helper_Functions::get_primary_term($post->ID, $taxonomy));
148
-
149
- // B. Get the first assigned term to this taxonomy
150
- if(empty($replacement)) {
151
- $terms = wp_get_object_terms($post->ID, $taxonomy);
152
- $replacement = (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) ? $terms[0]->slug : "";
153
- }
154
-
155
- // Do the replacement
156
- $default_uri = ($replacement) ? str_replace("%{$taxonomy}%", $replacement, $default_uri) : $default_uri;
157
- }
158
- }
159
-
160
- $default_uri = preg_replace('/\s+/', '', $default_uri);
161
- $default_uri = str_replace('//', '/', $default_uri);
162
- $default_uri = trim($default_uri, "/");
163
-
164
- return $default_uri;
165
- }
166
-
167
- /**
168
- * The homepage should not use URI
169
- */
170
- function exclude_homepage($uris) {
171
- // Find the homepage URI
172
- $homepage_id = get_option('page_on_front');
173
- if(isset($uris[$homepage_id])) { unset($uris[$homepage_id]); }
174
-
175
- return $uris;
176
- }
177
-
178
- /**
179
- * Find & replace (bulk action)
180
- */
181
- static function posts_find_and_replace() {
182
- global $wpdb, $permalink_manager_uris;
183
-
184
- // Reset variables
185
- $updated_slugs_count = 0;
186
- $updated_array = array();
187
- $alert_type = $alert_content = $errors = '';
188
-
189
- // Prepare default variables from $_POST object
190
- $old_string = esc_sql($_POST['old_string']);
191
- $new_string = esc_sql($_POST['new_string']);
192
- $mode = isset($_POST['mode']) ? $_POST['mode'] : array('both');
193
- $post_types_array = ($_POST['post_types']);
194
- $post_statuses_array = ($_POST['post_statuses']);
195
- $post_types = implode("', '", $post_types_array);
196
- $post_statuses = implode("', '", $post_statuses_array);
197
-
198
- // Save the rows before they are updated to an array
199
- $posts_to_update = $wpdb->get_results("SELECT post_title, post_name, ID FROM {$wpdb->posts} WHERE post_status IN ('{$post_statuses}') AND post_type IN ('{$post_types}')", ARRAY_A);
200
-
201
- // Now if the array is not empty use IDs from each subarray as a key
202
- if($posts_to_update && empty($errors)) {
203
- foreach ($posts_to_update as $row) {
204
-
205
- // Prepare variables
206
- $old_post_name = $row['post_name'];
207
- $native_uri = self::get_default_post_uri($row['ID'], true);
208
- $default_uri = self::get_default_post_uri($row['ID']);
209
- $old_uri = (isset($permalink_manager_uris[$row['ID']])) ? $permalink_manager_uris[$row['ID']] : $default_uri;
210
- $old_slug = (strpos($old_uri, '/') !== false) ? substr($old_uri, strrpos($old_uri, '/') + 1) : $old_uri;
211
- $old_base = (strpos($old_uri, '/') !== false) ? substr($old_uri, 0, strrpos( $old_uri, '/') ) : '';
212
-
213
- // Process URI & slug
214
- $new_slug = str_replace($old_string, $new_string, $old_slug);
215
- $new_base = str_replace($old_string, $new_string, $old_base);
216
- $new_uri = (in_array($mode, array('both'))) ? trim("{$new_base}/{$new_slug}", "/") : trim("{$old_base}/{$new_slug}", "/");
217
- $new_post_name = (in_array($mode, array('post_names'))) ? str_replace($old_string, $new_string, $old_post_name) : $old_post_name; // Post name is changed only in first mode
218
-
219
- //print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n");
220
-
221
- // Check if native slug should be changed
222
- if(in_array($mode, array('post_names')) && ($old_post_name != $new_post_name)) {
223
- self::update_slug_by_id($new_post_name, $row['ID']);
224
- }
225
-
226
- if(($old_uri != $new_uri) || ($old_post_name != $new_post_name)) {
227
- $permalink_manager_uris[$row['ID']] = $new_uri;
228
- $updated_array[] = array('post_title' => $row['post_title'], 'ID' => $row['ID'], 'old_uri' => $old_uri, 'new_uri' => $new_uri, 'old_slug' => $old_post_name, 'new_slug' => $new_post_name);
229
- $updated_slugs_count++;
230
- }
231
-
232
- // Do not store default values
233
- if(isset($permalink_manager_uris[$row['ID']]) && ($new_uri == $native_uri)) {
234
- unset($permalink_manager_uris[$row['ID']]);
235
- }
236
- }
237
-
238
- // Filter array before saving
239
- $permalink_manager_uris = array_filter($permalink_manager_uris);
240
- update_option('permalink-manager-uris', $permalink_manager_uris);
241
-
242
- $output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count);
243
- wp_reset_postdata();
244
- }
245
-
246
- return ($output) ? $output : "";
247
- }
248
-
249
- /**
250
- * Regenerate slugs & bases (bulk action)
251
- */
252
- static function posts_regenerate_all_permalinks() {
253
- global $wpdb, $permalink_manager_uris, $permalink_manager_permastructs;
254
-
255
- // Setup needed variables
256
- $updated_slugs_count = 0;
257
- $updated_array = array();
258
- $alert_type = $alert_content = $errors = '';
259
-
260
- $post_types_array = ($_POST['post_types']) ? ($_POST['post_types']) : '';
261
- $post_statuses_array = ($_POST['post_statuses']) ? $_POST['post_statuses'] : '';
262
- $post_types = implode("', '", $post_types_array);
263
- $post_statuses = implode("', '", $post_statuses_array);
264
- $mode = isset($_POST['mode']) ? $_POST['mode'] : 'both';
265
-
266
- // Save the rows before they are updated to an array
267
- $posts_to_update = $wpdb->get_results("SELECT post_title, post_name, post_type, ID FROM {$wpdb->posts} WHERE post_status IN ('{$post_statuses}') AND post_type IN ('{$post_types}')", ARRAY_A);
268
-
269
- // Now if the array is not empty use IDs from each subarray as a key
270
- if($posts_to_update && empty($errors)) {
271
- foreach ($posts_to_update as $row) {
272
- $updated = 0;
273
-
274
- // Prepare variables
275
- $old_post_name = $row['post_name'];
276
- $native_uri = self::get_default_post_uri($row['ID'], true);
277
- $default_uri = self::get_default_post_uri($row['ID']);
278
- $old_uri = isset($permalink_manager_uris[$row['ID']]) ? trim($permalink_manager_uris[$row['ID']], "/") : $native_uri;
279
- $old_slug = (strpos($old_uri, '/') !== false) ? substr($old_uri, strrpos($old_uri, '/') + 1) : $old_uri;
280
- $correct_slug = sanitize_title($row['post_title']);
281
-
282
- // Process URI & slug
283
- $new_slug = wp_unique_post_slug($correct_slug, $row['ID'], get_post_status($row['ID']), get_post_type($row['ID']), null);
284
- $new_post_name = (in_array($mode, array('post_names'))) ? $new_slug : $old_post_name; // Post name is changed only in first mode
285
- $new_uri = (in_array($mode, array('both'))) ? $default_uri : str_replace($old_slug, $new_slug, $old_uri);
286
-
287
- //print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n");
288
-
289
- // Check if native slug should be changed
290
- if(in_array($mode, array('post_names')) && ($old_post_name != $new_post_name)) {
291
- self::update_slug_by_id($new_post_name, $row['ID']);
292
- }
293
-
294
- if(($old_uri != $new_uri) || ($old_post_name != $new_post_name)) {
295
- $permalink_manager_uris[$row['ID']] = $new_uri;
296
- $updated_array[] = array('post_title' => $row['post_title'], 'ID' => $row['ID'], 'old_uri' => $old_uri, 'new_uri' => $new_uri, 'old_slug' => $old_post_name, 'new_slug' => $new_post_name);
297
- $updated_slugs_count++;
298
- }
299
-
300
- // Do not store default values
301
- if(isset($permalink_manager_uris[$row['ID']]) && ($new_uri == $native_uri)) {
302
- unset($permalink_manager_uris[$row['ID']]);
303
- }
304
- }
305
-
306
- // Filter array before saving
307
- $permalink_manager_uris = array_filter($permalink_manager_uris);
308
- update_option('permalink-manager-uris', $permalink_manager_uris);
309
-
310
- $output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count);
311
- wp_reset_postdata();
312
- }
313
-
314
- return (!empty($output)) ? $output : "";
315
- }
316
-
317
- /**
318
- * Update all slugs & bases (bulk action)
319
- */
320
- static public function posts_update_all_permalinks() {
321
- global $permalink_manager_uris;
322
-
323
- // Setup needed variables
324
- $updated_slugs_count = 0;
325
- $updated_array = array();
326
-
327
- $old_uris = $permalink_manager_uris;
328
- $new_uris = isset($_POST['uri']) ? $_POST['uri'] : array();
329
-
330
- // Double check if the slugs and ids are stored in arrays
331
- if (!is_array($new_uris)) $new_uris = explode(',', $new_uris);
332
-
333
- if (!empty($new_uris)) {
334
- foreach($new_uris as $id => $new_uri) {
335
- // Prepare variables
336
- $this_post = get_post($id);
337
- $updated = '';
338
-
339
- // Get default & native URL
340
- $native_uri = self::get_default_post_uri($id, true);
341
- $default_uri = self::get_default_post_uri($id);
342
-
343
- $old_uri = isset($old_uris[$id]) ? trim($old_uris[$id], "/") : $native_uri;
344
-
345
- // Process new values - empty entries will be treated as default values
346
- $new_uri = preg_replace('/\s+/', '', $new_uri);
347
- $new_uri = (!empty($new_uri)) ? trim($new_uri, "/") : $default_uri;
348
- $new_slug = (strpos($new_uri, '/') !== false) ? substr($new_uri, strrpos($new_uri, '/') + 1) : $new_uri;
349
-
350
- //print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n");
351
-
352
- // Do not store native URIs
353
- if($new_uri == $native_uri) {
354
- unset($old_uris[$id]);
355
- }
356
-
357
- if($new_uri != $old_uri) {
358
- $old_uris[$id] = $new_uri;
359
- $updated_array[] = array('post_title' => get_the_title($id), 'ID' => $id, 'old_uri' => $old_uri, 'new_uri' => $new_uri);
360
- $updated_slugs_count++;
361
- }
362
-
363
- }
364
-
365
- // Filter array before saving & append the global
366
- $old_uris = $permalink_manager_uris = array_filter($old_uris);
367
- update_option('permalink-manager-uris', $old_uris);
368
-
369
- $output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count);
370
- }
371
-
372
- return ($output) ? $output : "";
373
- }
374
-
375
- /**
376
- * Update URI from "Edit Post" admin page
377
- */
378
- function update_post_uri($post_id, $post, $update) {
379
- global $permalink_manager_uris;
380
-
381
- // Ignore trashed items
382
- if($post->post_status == 'trash') return;
383
-
384
- // Fix for revisions
385
- $is_revision = wp_is_post_revision($post_id);
386
- $post_id = ($is_revision) ? $is_revision : $post_id;
387
- $post = get_post($post_id);
388
-
389
- $native_uri = self::get_default_post_uri($post, true);
390
- $old_uri = (isset($permalink_manager_uris[$post->ID])) ? $permalink_manager_uris[$post->ID] : $native_uri;
391
- $new_uri = '';
392
-
393
- // Check if user changed URI (available after post is saved)
394
- if(isset($_POST['custom_uri'])) {
395
- $new_uri = trim($_POST['custom_uri'], "/");
396
- }
397
-
398
- // A little hack (if user removes whole URI from input) ...
399
- $new_uri = ($new_uri) ? $new_uri : self::get_post_uri($post);
400
-
401
- // Do not store default values
402
- if(isset($permalink_manager_uris[$post->ID]) && ($new_uri == $native_uri)) {
403
- unset($permalink_manager_uris[$post->ID]);
404
- }
405
- // Save only changed URIs
406
- else if (($new_uri != $native_uri) && ($new_uri != $old_uri)) {
407
- $permalink_manager_uris[$post->ID] = $new_uri;
408
- }
409
-
410
- update_option('permalink-manager-uris', $permalink_manager_uris);
411
- }
412
-
413
- /**
414
- * Remove URI from options array after post is moved to the trash
415
- */
416
- function remove_post_uri($post_id) {
417
- global $permalink_manager_uris;
418
-
419
- // Check if the custom permalink is assigned to this post
420
- if(isset($permalink_manager_uris[$post_id])) {
421
- unset($permalink_manager_uris[$post_id]);
422
- }
423
-
424
- update_option('permalink-manager-uris', $permalink_manager_uris);
425
- }
426
-
427
- /**
428
- * Remove URI from options array after post is moved to the trash
429
- */
430
- function clear_uris($post_id) {
431
- $uris = $this->permalink_manager_uris;
432
-
433
- foreach($uris as $post_id => $uri) {
434
- $post_status = get_post_status($post_id);
435
- if(in_array($post_status, array('auto-draft', 'trash', ''))) {
436
- unset($uris[$post_id]);
437
- }
438
- }
439
-
440
- update_option('permalink-manager-uris', $uris);
441
- }
442
-
443
- }
444
-
445
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/core/permalink-manager-uri-actions.php DELETED
@@ -1,350 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Register all action hooks
5
- */
6
- class Permalink_Manager_Uri_Actions extends Permalink_Manager_Class {
7
-
8
- public function __construct() {
9
- add_action('admin_init', array($this, 'trigger_action'), 0);
10
-
11
- add_action( 'save_post', array($this, 'update_single_uri'), 10, 3 );
12
- add_action( 'wp_trash_post', array($this, 'remove_single_uri'), 10, 3 );
13
- }
14
-
15
- /**
16
- * Trigger the specific action
17
- */
18
- function trigger_action() {
19
- global $permalink_manager_before_sections_html, $permalink_manager_after_sections_html;
20
-
21
- // Triggered in "Permalink Editor" section
22
- if(isset($_POST['slug_editor']) && wp_verify_nonce($_POST['slug_editor'], 'uri_actions')) {
23
- $updated_list = $this->posts_update_all_permalinks();
24
-
25
- $updated_slugs_count = (isset($updated_list['updated_count']) && $updated_list['updated_count'] > 0) ? $updated_list['updated_count'] : false;
26
- $updated_slugs_array = ($updated_slugs_count) ? $updated_list['updated'] : '';
27
- }
28
- // Triggered in "Regenerate/Rest" section
29
- else if(isset($_POST['regenerate_posts']) && wp_verify_nonce($_POST['regenerate_posts'], 'uri_actions')) {
30
- $updated_list = $this->posts_regenerate_all_permalinks();
31
-
32
- $updated_slugs_count = (isset($updated_list['updated_count']) && $updated_list['updated_count'] > 0) ? $updated_list['updated_count'] : false;
33
- $updated_slugs_array = ($updated_slugs_count) ? $updated_list['updated'] : '';
34
- }
35
- // Triggered in "Find and Replace" section
36
- else if(isset($_POST['find_and_replace']) && wp_verify_nonce($_POST['find_and_replace'], 'uri_actions')) {
37
- $updated_list = $this->posts_find_and_replace();
38
-
39
- $updated_slugs_count = (isset($updated_list['updated_count']) && $updated_list['updated_count'] > 0) ? $updated_list['updated_count'] : false;
40
- $updated_slugs_array = ($updated_slugs_count) ? $updated_list['updated'] : '';
41
- }
42
-
43
- // 2. Display the slugs table (and append the globals)
44
- if(isset($updated_slugs_count)) {
45
- if($updated_slugs_count > 0) {
46
- $alert_content = sprintf( _n( '<strong>%d</strong> slug was updated!', '<strong>%d</strong> slugs were updated!', $updated_slugs_count, 'permalink-manager' ), $updated_slugs_count ) . ' ';
47
- $alert_content .= sprintf( __( '<a href="%s">Click here</a> to go to the list of updated slugs', 'permalink-manager' ), '#updated-list');
48
-
49
- $permalink_manager_before_sections_html .= Permalink_Manager_Admin_Functions::get_alert_message($alert_content, 'updated');
50
- $permalink_manager_after_sections_html .= Permalink_Manager_Admin_Functions::display_updated_slugs($updated_slugs_array);
51
- } else {
52
- $alert_content = __( '<strong>No slugs</strong> were updated!', 'permalink-manager' );
53
- $permalink_manager_before_sections_html .= Permalink_Manager_Admin_Functions::get_alert_message($alert_content, 'error');
54
- }
55
- }
56
- }
57
-
58
- /**
59
- * Find & replace (bulk action)
60
- */
61
- static function posts_find_and_replace() {
62
- global $wpdb, $permalink_manager_uris;
63
-
64
- // Reset variables
65
- $updated_slugs_count = 0;
66
- $updated_array = array();
67
- $alert_type = $alert_content = $errors = '';
68
-
69
- // Prepare default variables from $_POST object
70
- $old_string = esc_sql($_POST['old_string']);
71
- $new_string = esc_sql($_POST['new_string']);
72
- $mode = isset($_POST['mode']) ? $_POST['mode'] : array('both');
73
- $post_types_array = ($_POST['post_types']);
74
- $post_statuses_array = ($_POST['post_statuses']);
75
- $post_types = implode("', '", $post_types_array);
76
- $post_statuses = implode("', '", $post_statuses_array);
77
-
78
- // Save the rows before they are updated to an array
79
- $posts_to_update = $wpdb->get_results("SELECT post_title, post_name, ID FROM {$wpdb->posts} WHERE post_status IN ('{$post_statuses}') AND post_type IN ('{$post_types}')", ARRAY_A);
80
-
81
- // Now if the array is not empty use IDs from each subarray as a key
82
- if($posts_to_update && empty($errors)) {
83
- foreach ($posts_to_update as $row) {
84
-
85
- // Prepare variables
86
- $old_post_name = $row['post_name'];
87
- $native_uri = Permalink_Manager_Post_URI_Functions::get_default_post_uri($row['ID'], true);
88
- $default_uri = Permalink_Manager_Post_URI_Functions::get_default_post_uri($row['ID']);
89
- $old_uri = (isset($permalink_manager_uris[$row['ID']])) ? $permalink_manager_uris[$row['ID']] : $default_uri;
90
- $old_slug = (strpos($old_uri, '/') !== false) ? substr($old_uri, strrpos($old_uri, '/') + 1) : $old_uri;
91
- $old_base = (strpos($old_uri, '/') !== false) ? substr($old_uri, 0, strrpos( $old_uri, '/') ) : '';
92
-
93
- // Process URI & slug
94
- $new_slug = str_replace($old_string, $new_string, $old_slug);
95
- $new_base = str_replace($old_string, $new_string, $old_base);
96
- $new_uri = (in_array($mode, array('both'))) ? trim("{$new_base}/{$new_slug}", "/") : trim("{$old_base}/{$new_slug}", "/");
97
- $new_post_name = (in_array($mode, array('post_names'))) ? str_replace($old_string, $new_string, $old_post_name) : $old_post_name; // Post name is changed only in first mode
98
-
99
- //print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n");
100
-
101
- // Check if native slug should be changed
102
- if(in_array($mode, array('post_names')) && ($old_post_name != $new_post_name)) {
103
- Permalink_Manager_Post_URI_Functions::update_slug_by_id($new_post_name, $row['ID']);
104
- }
105
-
106
- if(($old_uri != $new_uri) || ($old_post_name != $new_post_name)) {
107
- $permalink_manager_uris[$row['ID']] = $new_uri;
108
- $updated_array[] = array('post_title' => $row['post_title'], 'ID' => $row['ID'], 'old_uri' => $old_uri, 'new_uri' => $new_uri, 'old_slug' => $old_post_name, 'new_slug' => $new_post_name);
109
- $updated_slugs_count++;
110
- }
111
-
112
- // Do not store default values
113
- if(isset($permalink_manager_uris[$row['ID']]) && ($new_uri == $native_uri)) {
114
- unset($permalink_manager_uris[$row['ID']]);
115
- }
116
- }
117
-
118
- // Filter array before saving
119
- $permalink_manager_uris = array_filter($permalink_manager_uris);
120
- update_option('permalink-manager-uris', $permalink_manager_uris);
121
-
122
- $output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count);
123
- wp_reset_postdata();
124
- }
125
-
126
- return ($output) ? $output : "";
127
- }
128
-
129
- /**
130
- * Regenerate slugs & bases (bulk action)
131
- */
132
- static function posts_regenerate_all_permalinks() {
133
- global $wpdb, $permalink_manager_uris, $permalink_manager_permastructs;
134
-
135
- // Setup needed variables
136
- $updated_slugs_count = 0;
137
- $updated_array = array();
138
- $alert_type = $alert_content = $errors = '';
139
-
140
- // Check if post types & statuses are not empty
141
- if(empty($_POST['post_types']) || empty($_POST['post_statuses'])) { return false; }
142
-
143
- $post_types_array = ($_POST['post_types']) ? ($_POST['post_types']) : '';
144
- $post_statuses_array = ($_POST['post_statuses']) ? $_POST['post_statuses'] : '';
145
- $post_types = implode("', '", $post_types_array);
146
- $post_statuses = implode("', '", $post_statuses_array);
147
- $mode = isset($_POST['mode']) ? $_POST['mode'] : 'both';
148
-
149
- // Save the rows before they are updated to an array
150
- $posts_to_update = $wpdb->get_results("SELECT post_title, post_name, post_type, ID FROM {$wpdb->posts} WHERE post_status IN ('{$post_statuses}') AND post_type IN ('{$post_types}')", ARRAY_A);
151
-
152
- // Now if the array is not empty use IDs from each subarray as a key
153
- if($posts_to_update && empty($errors)) {
154
- foreach ($posts_to_update as $row) {
155
- $updated = 0;
156
-
157
- // Prepare variables
158
- $old_post_name = $row['post_name'];
159
- $native_uri = Permalink_Manager_Post_URI_Functions::get_default_post_uri($row['ID'], true);
160
- $default_uri = Permalink_Manager_Post_URI_Functions::get_default_post_uri($row['ID']);
161
- $old_uri = isset($permalink_manager_uris[$row['ID']]) ? trim($permalink_manager_uris[$row['ID']], "/") : $native_uri;
162
- $old_slug = (strpos($old_uri, '/') !== false) ? substr($old_uri, strrpos($old_uri, '/') + 1) : $old_uri;
163
- $correct_slug = sanitize_title($row['post_title']);
164
-
165
- // Process URI & slug
166
- $new_slug = wp_unique_post_slug($correct_slug, $row['ID'], get_post_status($row['ID']), get_post_type($row['ID']), null);
167
- $new_post_name = (in_array($mode, array('post_names'))) ? $new_slug : $old_post_name; // Post name is changed only in first mode
168
- $new_uri = (in_array($mode, array('both'))) ? $default_uri : str_replace($old_slug, $new_slug, $old_uri);
169
-
170
- //print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n");
171
-
172
- // Check if native slug should be changed
173
- if(in_array($mode, array('post_names')) && ($old_post_name != $new_post_name)) {
174
- Permalink_Manager_Post_URI_Functions::update_slug_by_id($new_post_name, $row['ID']);
175
- }
176
-
177
- if(($old_uri != $new_uri) || ($old_post_name != $new_post_name)) {
178
- $permalink_manager_uris[$row['ID']] = $new_uri;
179
- $updated_array[] = array('post_title' => $row['post_title'], 'ID' => $row['ID'], 'old_uri' => $old_uri, 'new_uri' => $new_uri, 'old_slug' => $old_post_name, 'new_slug' => $new_post_name);
180
- $updated_slugs_count++;
181
- }
182
-
183
- // Do not store default values
184
- if(isset($permalink_manager_uris[$row['ID']]) && ($new_uri == $native_uri)) {
185
- unset($permalink_manager_uris[$row['ID']]);
186
- }
187
- }
188
-
189
- // Filter array before saving
190
- $permalink_manager_uris = array_filter($permalink_manager_uris);
191
- update_option('permalink-manager-uris', $permalink_manager_uris);
192
-
193
- $output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count);
194
- wp_reset_postdata();
195
- }
196
-
197
- return (!empty($output)) ? $output : "";
198
- }
199
-
200
- /**
201
- * Update all slugs & bases (bulk action)
202
- */
203
- public function posts_update_all_permalinks() {
204
- global $permalink_manager_uris;
205
-
206
- // Setup needed variables
207
- $updated_slugs_count = 0;
208
- $updated_array = array();
209
-
210
- $old_uris = $permalink_manager_uris;
211
- $new_uris = isset($_POST['uri']) ? $_POST['uri'] : array();
212
-
213
- // Double check if the slugs and ids are stored in arrays
214
- if (!is_array($new_uris)) $new_uris = explode(',', $new_uris);
215
-
216
- if (!empty($new_uris)) {
217
- foreach($new_uris as $id => $new_uri) {
218
- // Prepare variables
219
- $this_post = get_post($id);
220
- $updated = '';
221
-
222
- // Get default & native URL
223
- $native_uri = Permalink_Manager_Post_URI_Functions::get_default_post_uri($id, true);
224
- $default_uri = Permalink_Manager_Post_URI_Functions::get_default_post_uri($id);
225
-
226
- $old_uri = isset($old_uris[$id]) ? trim($old_uris[$id], "/") : $native_uri;
227
-
228
- // Process new values - empty entries will be treated as default values
229
- $new_uri = preg_replace('/\s+/', '', $new_uri);
230
- $new_uri = (!empty($new_uri)) ? trim($new_uri, "/") : $default_uri;
231
- $new_slug = (strpos($new_uri, '/') !== false) ? substr($new_uri, strrpos($new_uri, '/') + 1) : $new_uri;
232
-
233
- //print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n");
234
-
235
- // Do not store native URIs
236
- if($new_uri == $native_uri) {
237
- unset($old_uris[$id]);
238
- }
239
-
240
- if($new_uri != $old_uri) {
241
- $old_uris[$id] = $new_uri;
242
- $updated_array[] = array('post_title' => get_the_title($id), 'ID' => $id, 'old_uri' => $old_uri, 'new_uri' => $new_uri);
243
- $updated_slugs_count++;
244
- }
245
-
246
- }
247
-
248
- // Filter array before saving & append the global
249
- $old_uris = $permalink_manager_uris = array_filter($old_uris);
250
- update_option('permalink-manager-uris', $old_uris);
251
-
252
- $output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count);
253
- }
254
-
255
- return ($output) ? $output : "";
256
- }
257
-
258
- /**
259
- * Remove URI from options array after post is moved to the trash
260
- */
261
- function clear_uris($post_id) {
262
- $uris = $this->permalink_manager_uris;
263
-
264
- foreach($uris as $post_id => $uri) {
265
- $post_status = get_post_status($post_id);
266
- if(in_array($post_status, array('auto-draft', 'trash', ''))) {
267
- unset($uris[$post_id]);
268
- }
269
- }
270
-
271
- update_option('permalink-manager-uris', $uris);
272
- }
273
-
274
- /**
275
- * Update permastructs
276
- */
277
- static function update_permastructs() {
278
- // Setup needed variables
279
- $alert_type = $alert_content = $errors = '';
280
- $permastructs = get_option('permalink-manager-permastructs', array());
281
- $new_permastructs = array_filter($_POST['permalink-manager']['custom-permastructs']);
282
-
283
- foreach($new_permastructs as $post_type => $new_permstruct) {
284
- $default_permastruct = Permalink_Manager_Helper_Functions::get_default_permastruct($post_type, true);
285
- $permastructs[$post_type] = trim(preg_replace('/\s+/', '', $new_permstruct), "/");
286
-
287
- // Do not save default permastructs
288
- if($default_permastruct == $new_permstruct) {
289
- unset($permastructs[$post_type]);
290
- }
291
- }
292
-
293
- update_option('permalink-manager-permastructs', $permastructs);
294
-
295
- return "";
296
- }
297
-
298
- /**
299
- * Update URI from "Edit Post" admin page
300
- */
301
- function update_single_uri($post_id, $post, $update) {
302
- global $permalink_manager_uris;
303
-
304
- // Ignore trashed items
305
- if($post->post_status == 'trash') return;
306
-
307
- // Fix for revisions
308
- $is_revision = wp_is_post_revision($post_id);
309
- $post_id = ($is_revision) ? $is_revision : $post_id;
310
- $post = get_post($post_id);
311
-
312
- $native_uri = Permalink_Manager_Post_URI_Functions::get_default_post_uri($post, true);
313
- $old_uri = (isset($permalink_manager_uris[$post->ID])) ? $permalink_manager_uris[$post->ID] : $native_uri;
314
- $new_uri = '';
315
-
316
- // Check if user changed URI (available after post is saved)
317
- if(isset($_POST['custom_uri'])) {
318
- $new_uri = trim($_POST['custom_uri'], "/");
319
- }
320
-
321
- // A little hack (if user removes whole URI from input) ...
322
- $new_uri = ($new_uri) ? $new_uri : Permalink_Manager_Post_URI_Functions::get_post_uri($post);
323
-
324
- // Do not store default values
325
- if(isset($permalink_manager_uris[$post->ID]) && ($new_uri == $native_uri)) {
326
- unset($permalink_manager_uris[$post->ID]);
327
- }
328
- // Save only changed URIs
329
- else if (($new_uri != $native_uri) && ($new_uri != $old_uri)) {
330
- $permalink_manager_uris[$post->ID] = $new_uri;
331
- }
332
-
333
- update_option('permalink-manager-uris', $permalink_manager_uris);
334
- }
335
-
336
- /**
337
- * Remove URI from options array after post is moved to the trash
338
- */
339
- function remove_single_uri($post_id) {
340
- global $permalink_manager_uris;
341
-
342
- // Check if the custom permalink is assigned to this post
343
- if(isset($permalink_manager_uris[$post_id])) {
344
- unset($permalink_manager_uris[$post_id]);
345
- }
346
-
347
- update_option('permalink-manager-uris', $permalink_manager_uris);
348
- }
349
-
350
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/core/permalink-manager-uri-functions-post.php ADDED
@@ -0,0 +1,449 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Additional functions used in classes and another subclasses
5
+ */
6
+ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
7
+
8
+ public function __construct() {
9
+ add_filter( 'get_sample_permalink_html', array($this, 'edit_uri_box'), 999, 4 );
10
+ add_filter( '_get_page_link', array($this, 'custom_post_permalinks'), 999, 2);
11
+ add_filter( 'page_link', array($this, 'custom_post_permalinks'), 999, 2);
12
+ add_filter( 'post_link', array($this, 'custom_post_permalinks'), 999, 2);
13
+ add_filter( 'post_type_link', array($this, 'custom_post_permalinks'), 999, 2);
14
+ add_filter( 'permalink-manager-uris', array($this, 'exclude_homepage'), 999, 2);
15
+ add_action( 'save_post', array($this, 'update_post_uri'), 10, 3 );
16
+ add_action( 'wp_trash_post', array($this, 'remove_post_uri'), 10, 3 );
17
+ }
18
+
19
+ /**
20
+ * Change permalinks for posts, pages & custom post types
21
+ */
22
+ function custom_post_permalinks($permalink, $post) {
23
+ global $wp_rewrite, $permalink_manager_uris, $sitepress_settings;
24
+
25
+ $post = (is_integer($post)) ? get_post($post) : $post;
26
+ $post_type = $post->post_type;
27
+
28
+ // Apend the language code as a non-editable prefix
29
+ if(isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 1) {
30
+ $post_lang_details = apply_filters('wpml_post_language_details', NULL, $post->ID);
31
+ $language_code = (!empty($post_lang_details['language_code'])) ? "{$post_lang_details['language_code']}/" : '';
32
+ } else {
33
+ $language_code = "";
34
+ }
35
+
36
+ // Do not change permalink of frontpage
37
+ if(get_option('page_on_front') == $post->ID) { return $permalink; }
38
+ if(isset($permalink_manager_uris[$post->ID])) $permalink = get_bloginfo('wpurl') . "/{$language_code}{$permalink_manager_uris[$post->ID]}";
39
+
40
+ return $permalink;
41
+ }
42
+
43
+ /**
44
+ * Check if the provided slug is unique and then update it with SQL query.
45
+ */
46
+ static function update_slug_by_id($slug, $id) {
47
+ global $wpdb;
48
+
49
+ // Update slug and make it unique
50
+ $slug = (empty($slug)) ? sanitize_title(get_the_title($id)) : $slug;
51
+ $new_slug = wp_unique_post_slug($slug, $id, get_post_status($id), get_post_type($id), null);
52
+ $wpdb->query("UPDATE $wpdb->posts SET post_name = '$new_slug' WHERE ID = '$id'");
53
+
54
+ return $new_slug;
55
+ }
56
+
57
+ /**
58
+ * Get the active URI
59
+ */
60
+ public static function get_post_uri($post_id, $native_uri = false) {
61
+ global $permalink_manager_uris;
62
+
63
+ // Check if input is post object
64
+ $post_id = (isset($post_id->ID)) ? $post_id->ID : $post_id;
65
+
66
+ $final_uri = (!empty($permalink_manager_uris[$post_id])) ? $permalink_manager_uris[$post_id] : self::get_default_post_uri($post_id, $native_uri);
67
+ return $final_uri;
68
+ }
69
+
70
+ /**
71
+ * Get the default (not overwritten by the user) or native URI (unfiltered)
72
+ */
73
+ public static function get_default_post_uri($post, $native_uri = false) {
74
+ global $permalink_manager_options, $permalink_manager_uris, $permalink_manager_permastructs, $sitepress_settings;
75
+
76
+ // Load all bases & post
77
+ $post = is_object($post) ? $post : get_post($post);
78
+ $post_id = $post->ID;
79
+ $post_type = $post->post_type;
80
+ $post_name = $post->post_name;
81
+
82
+ // Get the permastruct
83
+ $default_permastruct = Permalink_Manager_Helper_Functions::get_default_permastruct($post_type);
84
+ if($native_uri) {
85
+ $permastruct = $default_permastruct;
86
+ } else {
87
+ $permastruct = (!empty($permalink_manager_permastructs['post_types'][$post_type])) ? $permalink_manager_permastructs['post_types'][$post_type] : $default_permastruct;
88
+ }
89
+
90
+ $default_base = (!empty($permastruct)) ? trim($permastruct, '/') : "";
91
+
92
+ // 1A. Get the date
93
+ $date = explode(" ", date('Y m d H i s', strtotime($post->post_date)));
94
+
95
+ // 1B. Get the author (if needed)
96
+ $author = '';
97
+ if ( strpos($default_base, '%author%') !== false ) {
98
+ $authordata = get_userdata($post->post_author);
99
+ $author = $authordata->user_nicename;
100
+ }
101
+
102
+ // 2. Fix for hierarchical CPT (start)
103
+ $full_slug = ($native_uri == false) ? apply_filters('permalink_manager_filter_default_post_slug', get_page_uri($post), $post) : get_page_uri($post);
104
+ $post_type_tag = Permalink_Manager_Helper_Functions::get_post_tag($post_type);
105
+
106
+ // 3A. Do the replacement (post tag is removed now to enable support for hierarchical CPT)
107
+ $tags = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', '%post_id%', '%author%', $post_type_tag);
108
+ $replacements = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->ID, $author, '');
109
+ $default_uri = str_replace($tags, $replacements, "{$default_base}/{$full_slug}");
110
+
111
+ // 3B. Replace taxonomies
112
+ $taxonomies = get_taxonomies();
113
+
114
+ if($taxonomies) {
115
+ foreach($taxonomies as $taxonomy) {
116
+ // A. Try to use Yoast SEO Primary Term
117
+ $replacement = Permalink_Manager_Helper_Functions::get_primary_term($post->ID, $taxonomy);
118
+
119
+ // B. Get the first assigned term to this taxonomy
120
+ if(empty($replacement)) {
121
+ $terms = wp_get_object_terms($post->ID, $taxonomy);
122
+ $replacement = (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) ? $terms[0]->slug : "";
123
+ }
124
+
125
+ // Do the replacement
126
+ $default_uri = (!empty($replacement)) ? str_replace("%{$taxonomy}%", $replacement, $default_uri) : $default_uri;
127
+ }
128
+ }
129
+
130
+ $default_uri = preg_replace('/\s+/', '', $default_uri);
131
+ $default_uri = str_replace('//', '/', $default_uri);
132
+ $default_uri = trim($default_uri, "/");
133
+
134
+ return $default_uri;
135
+ }
136
+
137
+ /**
138
+ * The homepage should not use URI
139
+ */
140
+ function exclude_homepage($uris) {
141
+ // Find the homepage URI
142
+ $homepage_id = get_option('page_on_front');
143
+ if(isset($uris[$homepage_id])) { unset($uris[$homepage_id]); }
144
+
145
+ return $uris;
146
+ }
147
+
148
+ /**
149
+ * Find & replace (bulk action)
150
+ */
151
+ public static function find_and_replace() {
152
+ global $wpdb, $permalink_manager_uris;
153
+
154
+ // Check if post types & statuses are not empty
155
+ if(empty($_POST['post_types']) || empty($_POST['post_statuses'])) { return false; }
156
+
157
+ // Reset variables
158
+ $updated_slugs_count = 0;
159
+ $updated_array = array();
160
+ $alert_type = $alert_content = $errors = '';
161
+
162
+ // Prepare default variables from $_POST object
163
+ $old_string = esc_sql($_POST['old_string']);
164
+ $new_string = esc_sql($_POST['new_string']);
165
+ $mode = isset($_POST['mode']) ? $_POST['mode'] : array('both');
166
+ $post_types_array = ($_POST['post_types']);
167
+ $post_statuses_array = ($_POST['post_statuses']);
168
+ $post_types = implode("', '", $post_types_array);
169
+ $post_statuses = implode("', '", $post_statuses_array);
170
+
171
+ // Save the rows before they are updated to an array
172
+ $posts_to_update = $wpdb->get_results("SELECT post_title, post_name, ID FROM {$wpdb->posts} WHERE post_status IN ('{$post_statuses}') AND post_type IN ('{$post_types}')", ARRAY_A);
173
+
174
+ // Now if the array is not empty use IDs from each subarray as a key
175
+ if($posts_to_update && empty($errors)) {
176
+ foreach ($posts_to_update as $row) {
177
+
178
+ // Prepare variables
179
+ $old_post_name = $row['post_name'];
180
+ $native_uri = self::get_default_post_uri($row['ID'], true);
181
+ $default_uri = self::get_default_post_uri($row['ID']);
182
+ $old_uri = (isset($permalink_manager_uris[$row['ID']])) ? $permalink_manager_uris[$row['ID']] : $default_uri;
183
+ $old_slug = (strpos($old_uri, '/') !== false) ? substr($old_uri, strrpos($old_uri, '/') + 1) : $old_uri;
184
+ $old_base = (strpos($old_uri, '/') !== false) ? substr($old_uri, 0, strrpos( $old_uri, '/') ) : '';
185
+
186
+ // Process URI & slug
187
+ $new_slug = str_replace($old_string, $new_string, $old_slug);
188
+ $new_base = str_replace($old_string, $new_string, $old_base);
189
+ $new_uri = (in_array($mode, array('both'))) ? trim("{$new_base}/{$new_slug}", "/") : trim("{$old_base}/{$new_slug}", "/");
190
+ $new_post_name = (in_array($mode, array('post_names'))) ? str_replace($old_string, $new_string, $old_post_name) : $old_post_name; // Post name is changed only in first mode
191
+
192
+ //print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n");
193
+
194
+ // Check if native slug should be changed
195
+ if(in_array($mode, array('post_names')) && ($old_post_name != $new_post_name)) {
196
+ self::update_slug_by_id($new_post_name, $row['ID']);
197
+ }
198
+
199
+ if(($old_uri != $new_uri) || ($old_post_name != $new_post_name)) {
200
+ $permalink_manager_uris[$row['ID']] = $new_uri;
201
+ $updated_array[] = array('post_title' => $row['post_title'], 'ID' => $row['ID'], 'old_uri' => $old_uri, 'new_uri' => $new_uri, 'old_slug' => $old_post_name, 'new_slug' => $new_post_name);
202
+ $updated_slugs_count++;
203
+ }
204
+
205
+ // Do not store default values
206
+ if(isset($permalink_manager_uris[$row['ID']]) && ($new_uri == $native_uri)) {
207
+ unset($permalink_manager_uris[$row['ID']]);
208
+ }
209
+ }
210
+
211
+ // Filter array before saving
212
+ $permalink_manager_uris = array_filter($permalink_manager_uris);
213
+ update_option('permalink-manager-uris', $permalink_manager_uris);
214
+
215
+ $output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count);
216
+ wp_reset_postdata();
217
+ }
218
+
219
+ return ($output) ? $output : "";
220
+ }
221
+
222
+ /**
223
+ * Regenerate slugs & bases (bulk action)
224
+ */
225
+ static function regenerate_all_permalinks() {
226
+ global $wpdb, $permalink_manager_uris;
227
+
228
+ // Check if post types & statuses are not empty
229
+ if(empty($_POST['post_types']) || empty($_POST['post_statuses'])) { return false; }
230
+
231
+ // Setup needed variables
232
+ $updated_slugs_count = 0;
233
+ $updated_array = array();
234
+ $alert_type = $alert_content = $errors = '';
235
+
236
+ $post_types_array = ($_POST['post_types']) ? ($_POST['post_types']) : '';
237
+ $post_statuses_array = ($_POST['post_statuses']) ? $_POST['post_statuses'] : '';
238
+ $post_types = implode("', '", $post_types_array);
239
+ $post_statuses = implode("', '", $post_statuses_array);
240
+ $mode = isset($_POST['mode']) ? $_POST['mode'] : 'both';
241
+
242
+ // Save the rows before they are updated to an array
243
+ $posts_to_update = $wpdb->get_results("SELECT post_title, post_name, post_type, ID FROM {$wpdb->posts} WHERE post_status IN ('{$post_statuses}') AND post_type IN ('{$post_types}')", ARRAY_A);
244
+
245
+ // Now if the array is not empty use IDs from each subarray as a key
246
+ if($posts_to_update && empty($errors)) {
247
+ foreach ($posts_to_update as $row) {
248
+ $updated = 0;
249
+
250
+ // Prepare variables
251
+ $old_post_name = $row['post_name'];
252
+ $native_uri = self::get_default_post_uri($row['ID'], true);
253
+ $default_uri = self::get_default_post_uri($row['ID']);
254
+ $old_uri = isset($permalink_manager_uris[$row['ID']]) ? trim($permalink_manager_uris[$row['ID']], "/") : $native_uri;
255
+ $old_slug = (strpos($old_uri, '/') !== false) ? substr($old_uri, strrpos($old_uri, '/') + 1) : $old_uri;
256
+ $correct_slug = sanitize_title($row['post_title']);
257
+
258
+ // Process URI & slug
259
+ $new_slug = wp_unique_post_slug($correct_slug, $row['ID'], get_post_status($row['ID']), get_post_type($row['ID']), null);
260
+ $new_post_name = (in_array($mode, array('post_names'))) ? $new_slug : $old_post_name; // Post name is changed only in first mode
261
+ $new_uri = (in_array($mode, array('both'))) ? $default_uri : str_replace($old_slug, $new_slug, $old_uri);
262
+
263
+ //print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n");
264
+
265
+ // Check if native slug should be changed
266
+ if(in_array($mode, array('post_names')) && ($old_post_name != $new_post_name)) {
267
+ self::update_slug_by_id($new_post_name, $row['ID']);
268
+ }
269
+
270
+ if(($old_uri != $new_uri) || ($old_post_name != $new_post_name)) {
271
+ $permalink_manager_uris[$row['ID']] = $new_uri;
272
+ $updated_array[] = array('post_title' => $row['post_title'], 'ID' => $row['ID'], 'old_uri' => $old_uri, 'new_uri' => $new_uri, 'old_slug' => $old_post_name, 'new_slug' => $new_post_name);
273
+ $updated_slugs_count++;
274
+ }
275
+
276
+ // Do not store default values
277
+ if(isset($permalink_manager_uris[$row['ID']]) && ($new_uri == $native_uri)) {
278
+ unset($permalink_manager_uris[$row['ID']]);
279
+ }
280
+ }
281
+
282
+ // Filter array before saving
283
+ $permalink_manager_uris = array_filter($permalink_manager_uris);
284
+ update_option('permalink-manager-uris', $permalink_manager_uris);
285
+
286
+ $output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count);
287
+ wp_reset_postdata();
288
+ }
289
+
290
+ return (!empty($output)) ? $output : "";
291
+ }
292
+
293
+ /**
294
+ * Update all slugs & bases (bulk action)
295
+ */
296
+ static public function update_all_permalinks() {
297
+ global $permalink_manager_uris;
298
+
299
+ // Setup needed variables
300
+ $updated_slugs_count = 0;
301
+ $updated_array = array();
302
+
303
+ $old_uris = $permalink_manager_uris;
304
+ $new_uris = isset($_POST['uri']) ? $_POST['uri'] : array();
305
+
306
+ // Double check if the slugs and ids are stored in arrays
307
+ if (!is_array($new_uris)) $new_uris = explode(',', $new_uris);
308
+
309
+ if (!empty($new_uris)) {
310
+ foreach($new_uris as $id => $new_uri) {
311
+ // Prepare variables
312
+ $this_post = get_post($id);
313
+ $updated = '';
314
+
315
+ // Get default & native URL
316
+ $native_uri = self::get_default_post_uri($id, true);
317
+ $default_uri = self::get_default_post_uri($id);
318
+
319
+ $old_uri = isset($old_uris[$id]) ? trim($old_uris[$id], "/") : $native_uri;
320
+
321
+ // Process new values - empty entries will be treated as default values
322
+ $new_uri = preg_replace('/\s+/', '', $new_uri);
323
+ $new_uri = (!empty($new_uri)) ? trim($new_uri, "/") : $default_uri;
324
+ $new_slug = (strpos($new_uri, '/') !== false) ? substr($new_uri, strrpos($new_uri, '/') + 1) : $new_uri;
325
+
326
+ //print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri}\n");
327
+
328
+ if($new_uri != $old_uri) {
329
+ $old_uris[$id] = $new_uri;
330
+ $updated_array[] = array('post_title' => get_the_title($id), 'ID' => $id, 'old_uri' => $old_uri, 'new_uri' => $new_uri);
331
+ $updated_slugs_count++;
332
+ }
333
+
334
+ // Do not store native URIs
335
+ if($new_uri == $native_uri) {
336
+ unset($old_uris[$id]);
337
+ }
338
+
339
+ }
340
+
341
+ // Filter array before saving & append the global
342
+ $old_uris = $permalink_manager_uris = array_filter($old_uris);
343
+ update_option('permalink-manager-uris', $old_uris);
344
+
345
+ //print_r($permalink_manager_uris);
346
+
347
+ $output = array('updated' => $updated_array, 'updated_count' => $updated_slugs_count);
348
+ }
349
+
350
+ return ($output) ? $output : "";
351
+ }
352
+
353
+ /**
354
+ * Allow to edit URIs from "Edit Post" admin pages
355
+ */
356
+ function edit_uri_box($html, $id, $new_title, $new_slug) {
357
+ global $post, $permalink_manager_uris, $sitepress_settings;
358
+
359
+ // Try to alter the slug in auto-drafts ...
360
+ $new_slug = (empty($new_slug) && !empty($new_title)) ? sanitize_title($new_title) : $new_slug;
361
+ // ... and saved drafts
362
+ $new_slug = (empty($new_slug) && !empty($post->post_title)) ? sanitize_title($post->post_title) : $new_slug;
363
+
364
+ // Do not do anything if new slug is empty
365
+ if(empty($new_slug)) { return $html; }
366
+
367
+ $html = preg_replace("/(<strong>(.*)<\/strong>)(.*)/is", "$1 ", $html);
368
+ $default_uri = self::get_default_post_uri($id);
369
+ $default_uri .= (empty($post->post_name)) ? apply_filters("permalink_manager_filter_default_post_draft_slug", "/{$new_slug}", $id) : "";
370
+ // Make sure that home URL ends with slash
371
+ $home_url = trim(get_bloginfo('wpurl'), "/") . "/";
372
+
373
+ // WPML - apend the language code as a non-editable prefix
374
+ if(isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 1) {
375
+ $post_lang_details = apply_filters('wpml_post_language_details', NULL, $id);
376
+ $language_code = (!empty($post_lang_details['language_code'])) ? $post_lang_details['language_code'] : '';
377
+
378
+ // Last instance - use language paramater from &_GET array
379
+ $language_code = (empty($language_code) && !empty($_GET['lang'])) ? $_GET['lang'] : $language_code;
380
+ } else {
381
+ $language_code = "";
382
+ }
383
+
384
+ // Append slash to the end of language code if it is not empty
385
+ $language_code .= ($language_code) ? "/" : "";
386
+
387
+ // Do not change anything if post is not saved yet (display sample permalink instead)
388
+ if(empty($post->post_status) || $post->post_status == 'auto-draft') {
389
+ $sample_permalink = $home_url . str_replace("//", "/", trim("{$language_code}{$default_uri}", "/"));
390
+
391
+ $html .= "<span><a href=\"{$sample_permalink}\">{$sample_permalink}</a></span>";
392
+ } else {
393
+ $uri = (!empty($permalink_manager_uris[$id])) ? $permalink_manager_uris[$id] : $default_uri;
394
+ $html .= "{$home_url}{$language_code} <span id=\"editable-post-name\"><input type='text' value='{$uri}' name='custom_uri'/></span>";
395
+ }
396
+
397
+ return $html;
398
+ }
399
+
400
+ /**
401
+ * Update URI from "Edit Post" admin page
402
+ */
403
+ function update_post_uri($post_id, $post, $update) {
404
+ global $permalink_manager_uris;
405
+
406
+ // Fix for revisions
407
+ $is_revision = wp_is_post_revision($post_id);
408
+ $post_id = ($is_revision) ? $is_revision : $post_id;
409
+ $post = get_post($post_id);
410
+
411
+ // Ignore auto-drafts & removed posts
412
+ if(in_array($post->post_status, array('auto-draft', 'trash')) || !isset($_POST['custom_uri'])) { return; }
413
+
414
+ $default_uri = self::get_default_post_uri($post_id);
415
+ $native_uri = self::get_default_post_uri($post_id, true);
416
+ $old_uri = (isset($permalink_manager_uris[$post->ID])) ? $permalink_manager_uris[$post->ID] : $native_uri;
417
+
418
+ // Use default URI if URI is cleared by user
419
+ $new_uri = (!empty($_POST['custom_uri'])) ? trim($_POST['custom_uri'], "/") : $default_uri;
420
+
421
+ // Do not store default values
422
+ if(isset($permalink_manager_uris[$post->ID]) && ($new_uri == $native_uri)) {
423
+ unset($permalink_manager_uris[$post->ID]);
424
+ }
425
+ // Save only changed URIs
426
+ else if (($new_uri != $native_uri) && ($new_uri != $old_uri)) {
427
+ $permalink_manager_uris[$post->ID] = $new_uri;
428
+ }
429
+
430
+ update_option('permalink-manager-uris', $permalink_manager_uris);
431
+ }
432
+
433
+ /**
434
+ * Remove URI from options array after post is moved to the trash
435
+ */
436
+ function remove_post_uri($post_id) {
437
+ global $permalink_manager_uris;
438
+
439
+ // Check if the custom permalink is assigned to this post
440
+ if(isset($permalink_manager_uris[$post_id])) {
441
+ unset($permalink_manager_uris[$post_id]);
442
+ }
443
+
444
+ update_option('permalink-manager-uris', $permalink_manager_uris);
445
+ }
446
+
447
+ }
448
+
449
+ ?>
includes/views/permalink-manager-advanced.php CHANGED
@@ -1,88 +1,88 @@
1
  <?php
2
 
3
  /**
4
- * Display the page where the slugs could be regenerated or replaced
5
- */
6
  class Permalink_Manager_Advanced extends Permalink_Manager_Class {
7
 
8
- public function __construct() {
9
- add_filter( 'permalink-manager-sections', array($this, 'add_advanced_section'), 1 );
10
- }
11
 
12
- public function add_advanced_section($admin_sections) {
13
- $admin_sections['advanced'] = array(
14
- 'name' => __('Advanced', 'permalink-manager'),
15
- 'function' => array('class' => 'Permalink_Manager_Advanced', 'method' => 'output')
16
- );
17
 
18
- return $admin_sections;
19
- }
20
 
21
- public function output() {
22
- global $permalink_manager_options, $permalink_manager_uris, $permalink_manager_permastructs, $wp_filter;
23
 
24
- // Get permalink hooks
25
- foreach(array('_get_page_link', 'post_link', 'page_link', 'post_type_link') as $hook) {
26
- $permalink_hooks[$hook] = json_encode($wp_filter[$hook]);
27
- }
28
 
29
- $sections_and_fields = apply_filters('permalink-manager-settings-fields', array(
30
- 'debug-data' => array(
31
- 'section_name' => __('Debug data', 'permalink-manager'),
32
- 'fields' => array(
33
- 'uris' => array(
34
- 'type' => 'textarea',
35
- 'description' => __('List of the URIs generated by this plugin.', 'permalink-manager'),
36
- 'label' => __('Array with URIs', 'permalink-manager'),
37
- 'input_class' => 'short-textarea widefat',
38
- 'value' => ($permalink_manager_uris) ? print_r($permalink_manager_uris, true) : ''
39
- ),
40
- 'permastructs' => array(
41
- 'type' => 'textarea',
42
- 'description' => __('List of the permastructures.', 'permalink-manager'),
43
- 'label' => __('Array with permastructures', 'permalink-manager'),
44
- 'input_class' => 'short-textarea widefat',
45
- 'value' => ($permalink_manager_permastructs) ? print_r($permalink_manager_permastructs, true) : ''
46
- ),
47
- 'settings' => array(
48
- 'type' => 'textarea',
49
- 'description' => __('Currently used plugin settings.', 'permalink-manager'),
50
- 'label' => __('Array with settings used in this plugin.', 'permalink-manager'),
51
- 'input_class' => 'short-textarea widefat',
52
- 'value' => print_r($permalink_manager_options, true)
53
- ),
54
- 'hooks' => array(
55
- 'type' => 'textarea',
56
- 'description' => __('Permalink hooks.', 'permalink-manager'),
57
- 'label' => __('Array with list of permalink hooks used on this website.', 'permalink-manager'),
58
- 'input_class' => 'short-textarea widefat',
59
- 'value' => print_r($permalink_hooks, true)
60
- )
61
- )
62
- )
63
- ));
64
 
65
- // Now get the HTML output
66
- $output = '';
67
- foreach($sections_and_fields as $section_id => $section) {
68
- $output .= "<h4>{$section['section_name']}</h4>";
69
- $output .= (isset($section['description'])) ? "<p class=\"description\">{$section['description']}</p>" : "";
70
- $output .= "<table class=\"form-table fixed-table\">";
71
 
72
- // Loop through all fields assigned to this section
73
- foreach($section['fields'] as $field_id => $field) {
74
- $field_name = "{$section_id}[$field_id]";
75
- $field['container'] = 'row';
76
 
77
- $output .= Permalink_Manager_Admin_Functions::generate_option_field($field_name, $field);
78
- }
79
 
80
- // End the section
81
- $output .= "</table>";
82
 
83
- }
84
-
85
- return $output;
86
- }
87
 
 
 
 
88
  }
1
  <?php
2
 
3
  /**
4
+ * Display the page where the slugs could be regenerated or replaced
5
+ */
6
  class Permalink_Manager_Advanced extends Permalink_Manager_Class {
7
 
8
+ public function __construct() {
9
+ add_filter( 'permalink-manager-sections', array($this, 'add_advanced_section'), 1 );
10
+ }
11
 
12
+ public function add_advanced_section($admin_sections) {
13
+ $admin_sections['advanced'] = array(
14
+ 'name' => __('Advanced', 'permalink-manager'),
15
+ 'function' => array('class' => 'Permalink_Manager_Advanced', 'method' => 'output')
16
+ );
17
 
18
+ return $admin_sections;
19
+ }
20
 
21
+ public function output() {
22
+ global $permalink_manager_options, $permalink_manager_uris, $permalink_manager_permastructs, $wp_filter;
23
 
24
+ // Get permalink hooks
25
+ foreach(array('_get_page_link', 'post_link', 'page_link', 'post_type_link') as $hook) {
26
+ $permalink_hooks[$hook] = json_encode($wp_filter[$hook]);
27
+ }
28
 
29
+ $sections_and_fields = apply_filters('permalink-manager-advanced-fields', array(
30
+ 'debug-data' => array(
31
+ 'section_name' => __('Debug data', 'permalink-manager'),
32
+ 'fields' => array(
33
+ 'uris' => array(
34
+ 'type' => 'textarea',
35
+ 'description' => __('List of the URIs generated by this plugin.', 'permalink-manager'),
36
+ 'label' => __('Array with URIs', 'permalink-manager'),
37
+ 'input_class' => 'short-textarea widefat',
38
+ 'value' => ($permalink_manager_uris) ? print_r($permalink_manager_uris, true) : ''
39
+ ),
40
+ 'permastructs' => array(
41
+ 'type' => 'textarea',
42
+ 'description' => __('List of the permastructures.', 'permalink-manager'),
43
+ 'label' => __('Array with permastructures', 'permalink-manager'),
44
+ 'input_class' => 'short-textarea widefat',
45
+ 'value' => ($permalink_manager_permastructs) ? print_r($permalink_manager_permastructs, true) : ''
46
+ ),
47
+ 'settings' => array(
48
+ 'type' => 'textarea',
49
+ 'description' => __('Currently used plugin settings.', 'permalink-manager'),
50
+ 'label' => __('Array with settings used in this plugin.', 'permalink-manager'),
51
+ 'input_class' => 'short-textarea widefat',
52
+ 'value' => print_r($permalink_manager_options, true)
53
+ ),
54
+ 'hooks' => array(
55
+ 'type' => 'textarea',
56
+ 'description' => __('Permalink hooks.', 'permalink-manager'),
57
+ 'label' => __('Array with list of permalink hooks used on this website.', 'permalink-manager'),
58
+ 'input_class' => 'short-textarea widefat',
59
+ 'value' => print_r($permalink_hooks, true)
60
+ )
61
+ )
62
+ )
63
+ ));
64
 
65
+ // Now get the HTML output
66
+ $output = '';
67
+ foreach($sections_and_fields as $section_id => $section) {
68
+ $output .= (isset($section['section_name'])) ? "<h3>{$section['section_name']}</h3>" : "";
69
+ $output .= (isset($section['description'])) ? "<p class=\"description\">{$section['description']}</p>" : "";
70
+ $output .= "<table class=\"form-table fixed-table\">";
71
 
72
+ // Loop through all fields assigned to this section
73
+ foreach($section['fields'] as $field_id => $field) {
74
+ $field_name = "{$section_id}[$field_id]";
75
+ $field['container'] = 'row';
76
 
77
+ $output .= Permalink_Manager_Admin_Functions::generate_option_field($field_name, $field);
78
+ }
79
 
80
+ // End the section
81
+ $output .= "</table>";
82
 
83
+ }
 
 
 
84
 
85
+ return $output;
86
+ }
87
+
88
  }
includes/views/permalink-manager-permastructs.php CHANGED
@@ -1,59 +1,92 @@
1
  <?php
2
 
3
  /**
4
- * Display the page where the slugs could be regenerated or replaced
5
- */
6
  class Permalink_Manager_Permastructs extends Permalink_Manager_Class {
7
 
8
- public function __construct() {
9
- add_filter( 'permalink-manager-sections', array($this, 'add_admin_section'), 1 );
10
- }
11
-
12
- public function add_admin_section($admin_sections) {
13
-
14
- $admin_sections['permastructs'] = array(
15
- 'name' => __('Permastructures', 'permalink-manager'),
16
- 'function' => array('class' => 'Permalink_Manager_Permastructs', 'method' => 'output')
17
- );
18
-
19
- return $admin_sections;
20
- }
21
-
22
- /**
23
- * Get the array with settings and render the HTML output
24
- */
25
- public function output() {
26
- global $permalink_manager_permastructs;
27
-
28
- $all_post_types = Permalink_Manager_Helper_Functions::get_post_types_array('full');
29
- $fields = array();
30
-
31
- // 2. Get all post types
32
- foreach($all_post_types as $post_type) {
33
-
34
- $default_permastruct = Permalink_Manager_Helper_Functions::get_default_permastruct($post_type['name'], true);
35
- $current_permastruct = isset($permalink_manager_permastructs[$post_type['name']]) ? $permalink_manager_permastructs[$post_type['name']] : '';
36
-
37
- $fields["permastructures[{$post_type['name']}]"] = array(
38
- 'label' => $post_type['label'],
39
- 'container' => 'row',
40
- 'input_class' => 'widefat',
41
- 'value' => $current_permastruct,
42
- 'placeholder' => $default_permastruct,
43
- 'type' => 'text'
44
- );
45
- }
46
-
47
- // 2. Display some notes
48
- $notes[] = sprintf( __('All available <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() . "\n";
49
- $notes[] = __('Each Custom Post Type should have unique permastructure.', 'permalink-manager');
50
- $notes[] = __('Please note that the following settings will be applied only to new posts.<br />If you would like to use the current permastructures settings, you will need to regenerate the posts\' URIs in <strong>"Tools -> Regnerate/Reset"</strong> section.', 'permalink-manager');
51
- $notes[] = __('To use the native permastruct please keep the field empty.', 'permalink-manager');
52
- $sidebar = '<h3>' . __('Usage Instructions', 'permalink-manager') . '</h3>';
53
- $sidebar .= "<ol><li>" . implode('</li><li>', $notes) . "</li></ol>";
54
-
55
- $output = Permalink_Manager_Admin_Functions::get_the_form($fields, 'columns-3', array('text' => __( 'Save permastructures', 'permalink-manager' ), 'class' => 'primary margin-top'), $sidebar, array('action' => 'save_settings', 'name' => 'permalink-manager-permastructs'));
56
- return $output;
57
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
  }
1
  <?php
2
 
3
  /**
4
+ * Display the page where the slugs could be regenerated or replaced
5
+ */
6
  class Permalink_Manager_Permastructs extends Permalink_Manager_Class {
7
 
8
+ public function __construct() {
9
+ add_filter( 'permalink-manager-sections', array($this, 'add_admin_section'), 1 );
10
+ }
11
+
12
+ public function add_admin_section($admin_sections) {
13
+
14
+ $admin_sections['permastructs'] = array(
15
+ 'name' => __('Permastructures', 'permalink-manager'),
16
+ 'function' => array('class' => 'Permalink_Manager_Permastructs', 'method' => 'output')
17
+ );
18
+
19
+ return $admin_sections;
20
+ }
21
+
22
+ public function get_fields() {
23
+ global $permalink_manager_permastructs;
24
+
25
+ $all_post_types = Permalink_Manager_Helper_Functions::get_post_types_array('full');
26
+ $woocommerce_icon = "<i class=\"woocommerce-icon woocommerce-cart\"></i>";
27
+
28
+ // 1. Get notes
29
+ $post_types_notes = wpautop(sprintf(__('All available <a href="%s" target="_blank">structure tags</a> for <strong>post types</strong> allowed are listed below.', 'permalink-manager'), "https://codex.wordpress.org/Using_Permalinks#Structure_Tags"));
30
+ $post_types_notes .= Permalink_Manager_Helper_Functions::get_all_structure_tags();
31
+ $post_types_notes .= wpautop(sprintf(__('Please note that some of them can be used only for particular post types\' settings.', 'permalink-manager'), "https://codex.wordpress.org/Using_Permalinks#Structure_Tags"));
32
+
33
+ // 2. Get fields
34
+ $fields = array(
35
+ 'post_types' => array(
36
+ 'section_name' => __('Post types', 'permalink-manager'),
37
+ 'container' => 'row',
38
+ 'append_content' => $post_types_notes,
39
+ 'fields' => array()
40
+ ),
41
+ /*'taxonomies' => array(
42
+ 'section_name' => __('Taxonomies', 'permalink-manager'),
43
+ 'container' => 'row',
44
+ 'append_content' => Permalink_Manager_Admin_Functions::pro_text(),
45
+ 'fields' => array()
46
+ )*/
47
+ );
48
+
49
+ // 2. Woocommerce support
50
+ /*if(class_exists('WooCommerce')) {
51
+ $fields['woocommerce'] = array(
52
+ 'section_name' => "{$woocommerce_icon} " . __('WooCommerce', 'permalink-manager'),
53
+ 'container' => 'row',
54
+ 'append_content' => Permalink_Manager_Admin_Functions::pro_text(),
55
+ 'fields' => array()
56
+ );
57
+ }*/
58
+
59
+ // 3. Append fields for all post types
60
+ foreach($all_post_types as $post_type) {
61
+
62
+ $default_permastruct = Permalink_Manager_Helper_Functions::get_default_permastruct($post_type['name'], true);
63
+ $current_permastruct = isset($permalink_manager_permastructs['post_types'][$post_type['name']]) ? $permalink_manager_permastructs['post_types'][$post_type['name']] : '';
64
+
65
+ $fields["post_types"]["fields"][$post_type['name']] = array(
66
+ 'label' => $post_type['label'],
67
+ 'container' => 'row',
68
+ 'input_class' => '',
69
+ 'value' => $current_permastruct,
70
+ 'placeholder' => $default_permastruct,
71
+ 'type' => 'permastruct'
72
+ );
73
+ }
74
+
75
+ return apply_filters('permalink-manager-permastructs-fields', $fields);
76
+ }
77
+
78
+ /**
79
+ * Get the array with settings and render the HTML output
80
+ */
81
+ public function output() {
82
+ global $permalink_manager_permastructs;
83
+
84
+ $output = wpautop(sprintf(__('This tool allows to overwrite the native permalink settings (permastructures) that can be edited <a href="%s" target="_blank">here</a>.', 'bis'), "#"));
85
+ $output .= wpautop(__('This tool <strong>automatically appends the slug to the end of permastructure</strong>, so there is no need to use them within the fields.', 'bis'));
86
+ $output .= wpautop(__('Each permastructure should be unique to prevent the problem with overlapping URLs.', 'bis'));
87
+ $output .= Permalink_Manager_Admin_Functions::get_the_form(self::get_fields(), '', array('text' => __( 'Save permastructures', 'permalink-manager' ), 'class' => 'primary margin-top'), '', array('action' => 'permalink-manager', 'name' => 'permalink_manager_permastructs'));
88
+
89
+ return $output;
90
+ }
91
 
92
  }
includes/views/permalink-manager-settings.php CHANGED
@@ -1,114 +1,119 @@
1
  <?php
2
 
3
  /**
4
- * Display the settings page
5
- */
6
  class Permalink_Manager_Settings extends Permalink_Manager_Class {
7
 
8
- public function __construct() {
9
- add_filter( 'permalink-manager-sections', array($this, 'add_admin_section'), 1 );
10
- add_filter( 'permalink-manager-options', array($this, 'default_settings'), 9 );
11
- }
12
 
13
- public function add_admin_section($admin_sections) {
14
- $admin_sections['settings'] = array(
15
- 'name' => __('Settings', 'permalink-manager'),
16
- 'function' => array('class' => 'Permalink_Manager_Settings', 'method' => 'output')
17
- );
18
 
19
- return $admin_sections;
20
- }
21
 
22
- /**
23
- * Set the initial/default settings
24
- */
25
- public function default_settings($settings) {
26
- $default_settings = apply_filters('permalink-manager-default-options', array(
27
- 'screen-options' => array(
28
- 'per_page' => 20,
29
- 'post_statuses' => array('publish'),
30
- 'post_types' => array('page', 'post')
31
- ),
32
- 'miscellaneous' => array(
33
- 'yoast_primary_term' => 1,
34
- 'redirect' => "302",
35
- 'canonical_redirect' => 1,
36
- )
37
- ));
38
 
39
- // Apply the default settings (if empty values) in all settings sections
40
- $final_settings = array();
41
- foreach($default_settings as $section => $fields) {
42
- $final_settings[$section] = (isset($settings[$section])) ? array_replace($fields, $settings[$section]) : $fields;
43
- }
 
 
 
 
 
 
 
 
44
 
45
- return $final_settings;
46
- }
 
 
 
47
 
48
- /**
49
- * Get the array with settings and render the HTML output
50
- */
51
- public function output() {
52
- // Get all registered post types array & statuses
53
- $all_post_statuses_array = get_post_statuses();
54
- $all_post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
55
 
56
- $sections_and_fields = apply_filters('permalink-manager-settings-fields', array(
57
- 'screen-options' => array(
58
- 'section_name' => __('Display settings', 'permalink-manager'),
59
- 'description' => __('Adjust the data displayed in "Permalink Editor" section.', 'permalink-manager'),
60
- 'fields' => array(
61
- 'per_page' => array(
62
- 'type' => 'number',
63
- 'label' => __('Per page', 'permalink-manager'),
64
- 'input_class' => 'settings-select'
65
- ),
66
- 'post_statuses' => array(
67
- 'type' => 'checkbox',
68
- 'label' => __('Post statuses', 'permalink-manager'),
69
- 'choices' => $all_post_statuses_array,
70
- 'select_all' => '',
71
- 'unselect_all' => '',
72
- ),
73
- 'post_types' => array(
74
- 'type' => 'checkbox',
75
- 'label' => __('Post types', 'permalink-manager'),
76
- 'choices' => $all_post_types,
77
- 'select_all' => '',
78
- 'unselect_all' => '',
79
- ),
80
- )
81
- ),
82
- 'miscellaneous' => array(
83
- 'section_name' => __('Miscellaneous & SEO functions', 'permalink-manager'),
84
- 'fields' => array(
85
- 'yoast_primary_term' => array(
86
- 'type' => 'select',
87
- 'label' => __('Primay term/category support', 'permalink-manager'),
88
- 'input_class' => 'settings-select',
89
- 'choices' => array(1 => __('Enable', 'permalink-manager'), 0 => __('Disable', 'permalink-manager')),
90
- 'description' => __('Used to generate default permalinks in pages, posts & custom post types. Works only when "Yoast SEO" plugin is enabled.', 'permalink-manager')
91
- ),
92
- 'redirect' => array(
93
- 'type' => 'select',
94
- 'label' => __('Redirect', 'permalink-manager'),
95
- 'input_class' => 'settings-select',
96
- 'choices' => array(0 => __('Disable', 'permalink-manager'), "301" => __('Enable "301 redirect"', 'permalink-manager'), "302" => __('Enable "302 redirect"', 'permalink-manager')),
97
- 'description' => __('If enabled - the visitors will be redirected from native permalinks to your custom permalinks. Please note that the redirects will work correctly only if native slug "post name" will not be changed.', 'permalink-manager')
98
- ),
99
- 'canonical_redirect' => array(
100
- 'type' => 'select',
101
- 'label' => __('Canonical redirect', 'permalink-manager'),
102
- 'input_class' => 'settings-select',
103
- 'choices' => array(0 => __('Disable', 'permalink-manager'), 1 => __('Enable', 'permalink-manager')),
104
- 'description' => __('This function allows Wordpress to correct the URLs used by the visitors.', 'permalink-manager')
105
- )
106
- )
107
- )
108
- ));
109
-
110
- $output = Permalink_Manager_Admin_Functions::get_the_form($sections_and_fields, '', array('text' => __( 'Save settings', 'permalink-manager' ), 'class' => 'primary margin-top'), '', array('action' => 'save_settings', 'name' => 'permalink-manager-options'));
111
- return $output;
112
- }
113
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  }
1
  <?php
2
 
3
  /**
4
+ * Display the settings page
5
+ */
6
  class Permalink_Manager_Settings extends Permalink_Manager_Class {
7
 
8
+ public function __construct() {
9
+ add_filter( 'permalink-manager-sections', array($this, 'add_admin_section'), 1 );
10
+ add_filter( 'permalink-manager-options', array($this, 'default_settings'), 9 );
11
+ }
12
 
13
+ public function add_admin_section($admin_sections) {
14
+ $admin_sections['settings'] = array(
15
+ 'name' => __('Settings', 'permalink-manager'),
16
+ 'function' => array('class' => 'Permalink_Manager_Settings', 'method' => 'output')
17
+ );
18
 
19
+ return $admin_sections;
20
+ }
21
 
22
+ /**
23
+ * Set the initial/default settings
24
+ */
25
+ public function default_settings($settings) {
26
+ $all_taxonomies = Permalink_Manager_Helper_Functions::get_taxonomies_array();
27
+ $all_post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
 
 
 
 
 
 
 
 
 
 
28
 
29
+ $default_settings = apply_filters('permalink-manager-default-options', array(
30
+ 'screen-options' => array(
31
+ 'per_page' => 20,
32
+ 'post_statuses' => array('publish'),
33
+ 'post_types' => $all_post_types,
34
+ 'taxonomies' => $all_taxonomies
35
+ ),
36
+ 'miscellaneous' => array(
37
+ 'yoast_primary_term' => 1,
38
+ 'redirect' => "302",
39
+ 'canonical_redirect' => 1,
40
+ )
41
+ ));
42
 
43
+ // Apply the default settings (if empty values) in all settings sections
44
+ $final_settings = array();
45
+ foreach($default_settings as $section => $fields) {
46
+ $final_settings[$section] = (isset($settings[$section])) ? array_replace($fields, $settings[$section]) : $fields;
47
+ }
48
 
49
+ return $final_settings;
50
+ }
 
 
 
 
 
51
 
52
+ /**
53
+ * Get the array with settings and render the HTML output
54
+ */
55
+ public function output() {
56
+ // Get all registered post types array & statuses
57
+ $all_post_statuses_array = get_post_statuses();
58
+ $all_post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
+ $sections_and_fields = apply_filters('permalink-manager-settings-fields', array(
61
+ 'screen-options' => array(
62
+ 'section_name' => __('Display settings', 'permalink-manager'),
63
+ 'description' => __('Adjust the data displayed in "Permalink Editor" section.', 'permalink-manager'),
64
+ 'container' => 'row',
65
+ 'fields' => array(
66
+ 'per_page' => array(
67
+ 'type' => 'number',
68
+ 'label' => __('Per page', 'permalink-manager'),
69
+ 'input_class' => 'settings-select'
70
+ ),
71
+ 'post_statuses' => array(
72
+ 'type' => 'checkbox',
73
+ 'label' => __('Post statuses', 'permalink-manager'),
74
+ 'choices' => $all_post_statuses_array,
75
+ 'select_all' => '',
76
+ 'unselect_all' => '',
77
+ ),
78
+ 'post_types' => array(
79
+ 'type' => 'checkbox',
80
+ 'label' => __('Post types', 'permalink-manager'),
81
+ 'choices' => $all_post_types,
82
+ 'select_all' => '',
83
+ 'unselect_all' => '',
84
+ )
85
+ )
86
+ ),
87
+ 'miscellaneous' => array(
88
+ 'section_name' => __('Miscellaneous & SEO functions', 'permalink-manager'),
89
+ 'container' => 'row',
90
+ 'fields' => array(
91
+ 'yoast_primary_term' => array(
92
+ 'type' => 'select',
93
+ 'label' => __('Primay term/category support', 'permalink-manager'),
94
+ 'input_class' => 'settings-select',
95
+ 'choices' => array(1 => __('Enable', 'permalink-manager'), 0 => __('Disable', 'permalink-manager')),
96
+ 'description' => __('Used to generate default permalinks in pages, posts & custom post types. Works only when "Yoast SEO" plugin is enabled.', 'permalink-manager')
97
+ ),
98
+ 'redirect' => array(
99
+ 'type' => 'select',
100
+ 'label' => __('Redirect', 'permalink-manager'),
101
+ 'input_class' => 'settings-select',
102
+ 'choices' => array(0 => __('Disable', 'permalink-manager'), "301" => __('Enable "301 redirect"', 'permalink-manager'), "302" => __('Enable "302 redirect"', 'permalink-manager')),
103
+ 'description' => __('If enabled - the visitors will be redirected from native permalinks to your custom permalinks. Please note that the redirects will work correctly only if native slug "post name" will not be changed.', 'permalink-manager')
104
+ ),
105
+ 'canonical_redirect' => array(
106
+ 'type' => 'select',
107
+ 'label' => __('Canonical redirect', 'permalink-manager'),
108
+ 'input_class' => 'settings-select',
109
+ 'choices' => array(0 => __('Disable', 'permalink-manager'), 1 => __('Enable', 'permalink-manager')),
110
+ 'description' => __('This function allows Wordpress to correct the URLs used by the visitors.', 'permalink-manager')
111
+ )
112
+ )
113
+ )
114
+ ));
115
+
116
+ $output = Permalink_Manager_Admin_Functions::get_the_form($sections_and_fields, '', array('text' => __( 'Save settings', 'permalink-manager' ), 'class' => 'primary margin-top'), '', array('action' => 'permalink-manager', 'name' => 'permalink_manager_options'));
117
+ return $output;
118
+ }
119
  }
includes/views/permalink-manager-tools.php CHANGED
@@ -1,124 +1,128 @@
1
  <?php
2
 
3
  /**
4
- * Display the page where the slugs could be regenerated or replaced
5
- */
6
  class Permalink_Manager_Tools extends Permalink_Manager_Class {
7
 
8
- public function __construct() {
9
- add_filter( 'permalink-manager-sections', array($this, 'add_admin_section'), 1 );
10
- }
11
-
12
- public function add_admin_section($admin_sections) {
13
-
14
- $admin_sections['tools'] = array(
15
- 'name' => __('Tools', 'permalink-manager'),
16
- 'subsections' => array(
17
- 'find_and_replace' => array(
18
- 'name' => __('Find and replace', 'permalink-manager'),
19
- 'function' => array('class' => 'Permalink_Manager_Tools', 'method' => 'find_and_replace_output')
20
- ),
21
- 'regenerate_slugs' => array(
22
- 'name' => __('Regenerate/Reset', 'permalink-manager'),
23
- 'function' => array('class' => 'Permalink_Manager_Tools', 'method' => 'regenerate_slugs_output')
24
- )
25
- )
26
- );
27
-
28
- return $admin_sections;
29
- }
30
-
31
- public function display_instructions() {
32
- $output = wpautop(sprintf(__('<h4>A MySQL backup is highly recommended before using "<em>Custom & native slugs (post names)</em>" mode!</h4>With this mode selected, <strong>post_name</strong> field (native slug) will be changed directly in <a href="%s"><strong>"posts"</strong></a> database table.', 'permalink-manager'), 'https://codex.wordpress.org/Database_Description#Table:_wp_posts'));
33
- return $output;
34
- }
35
-
36
- public function find_and_replace_output() {
37
- // Get all registered post types array & statuses
38
- $all_post_statuses_array = get_post_statuses();
39
- $all_post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
40
 
41
- $fields = array(
42
- array('group' => array(
43
- 'old_string' => array(
44
- 'label' => __( 'Find ...', 'permalink-manager' ),
45
- 'type' => 'text',
46
- 'container_class' => 'column column-1_2',
47
- 'input_class' => 'widefat'
48
- ),
49
- 'new_string' => array(
50
- 'label' => __( 'Replace with ...', 'permalink-manager' ),
51
- 'type' => 'text',
52
- 'container_class' => 'column column-1_2',
53
- 'input_class' => 'widefat'
54
- ),
55
- )),
 
 
 
 
 
 
 
 
 
 
 
 
56
  'mode' => array(
57
  'label' => __( 'Select mode', 'permalink-manager' ),
58
  'type' => 'select',
 
59
  'choices' => array('both' => '<strong>' . __('Full URIs', 'permalink-manager') . '</strong>', 'slugs' => '<strong>' . __('Only custom slugs', 'permalink-manager') . '</strong>', 'post_names' => '<strong>' . __('Custom & native slugs (post names)', 'permalink-manager') . '</strong>'),
60
  'default' => array('both'),
61
  ),
62
- 'post_types' => array(
63
  'label' => __( 'Filter by post types', 'permalink-manager' ),
64
  'type' => 'checkbox',
65
- 'default' => array('post', 'page'),
 
66
  'choices' => $all_post_types,
67
- 'select_all' => '',
68
- 'unselect_all' => '',
69
  ),
70
  'post_statuses' => array(
71
  'label' => __( 'Filter by post statuses', 'permalink-manager' ),
72
  'type' => 'checkbox',
73
- 'default' => array('publish'),
 
74
  'choices' => $all_post_statuses_array,
75
- 'select_all' => '',
76
- 'unselect_all' => '',
77
  )
78
  );
79
 
80
- $sidebar = '<h3>' . __('Important notes', 'permalink-manager') . '</h3>';
81
- $sidebar .= self::display_instructions();
82
 
83
- $output = Permalink_Manager_Admin_Functions::get_the_form($fields, 'columns-3', array('text' => __( 'Find and replace', 'permalink-manager' ), 'class' => 'primary margin-top'), $sidebar, array('action' => 'uri_actions', 'name' => 'find_and_replace'));
84
 
85
- return $output;
86
- }
87
 
88
- public function regenerate_slugs_output() {
89
- // Get all registered post types array & statuses
90
- $all_post_statuses_array = get_post_statuses();
91
- $all_post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
92
 
93
- $fields = array(
94
  'mode' => array(
95
  'label' => __( 'Select mode', 'permalink-manager' ),
96
  'type' => 'select',
 
97
  'choices' => array('both' => '<strong>' . __('Full URIs', 'permalink-manager') . '</strong>', 'slugs' => '<strong>' . __('Only custom slugs', 'permalink-manager') . '</strong>', 'post_names' => '<strong>' . __('Custom & native slugs (post names)', 'permalink-manager') . '</strong>'),
98
  ),
99
  'post_types' => array(
100
  'label' => __( 'Filter by post types', 'permalink-manager' ),
101
  'type' => 'checkbox',
102
- 'default' => array('post', 'page'),
 
103
  'choices' => $all_post_types,
104
- 'select_all' => '',
105
- 'unselect_all' => '',
106
  ),
107
  'post_statuses' => array(
108
  'label' => __( 'Filter by post statuses', 'permalink-manager' ),
109
  'type' => 'checkbox',
110
- 'default' => array('publish'),
 
111
  'choices' => $all_post_statuses_array,
112
- 'select_all' => '',
113
- 'unselect_all' => '',
114
  )
115
  );
116
 
117
- $sidebar = '<h3>' . __('Important notes', 'permalink-manager') . '</h3>';
118
- $sidebar .= self::display_instructions();
119
- $output = Permalink_Manager_Admin_Functions::get_the_form($fields, 'columns-3', array('text' => __( 'Regenerate', 'permalink-manager' ), 'class' => 'primary margin-top'), $sidebar, array('action' => 'uri_actions', 'name' => 'regenerate_posts'));
120
-
121
- return $output;
122
- }
123
 
 
 
124
  }
1
  <?php
2
 
3
  /**
4
+ * Display the page where the slugs could be regenerated or replaced
5
+ */
6
  class Permalink_Manager_Tools extends Permalink_Manager_Class {
7
 
8
+ public function __construct() {
9
+ add_filter( 'permalink-manager-sections', array($this, 'add_admin_section'), 1 );
10
+ }
11
+
12
+ public function add_admin_section($admin_sections) {
13
+
14
+ $admin_sections['tools'] = array(
15
+ 'name' => __('Tools', 'permalink-manager'),
16
+ 'subsections' => array(
17
+ 'find_and_replace' => array(
18
+ 'name' => __('Find and replace', 'permalink-manager'),
19
+ 'function' => array('class' => 'Permalink_Manager_Tools', 'method' => 'find_and_replace_output')
20
+ ),
21
+ 'regenerate_slugs' => array(
22
+ 'name' => __('Regenerate/Reset', 'permalink-manager'),
23
+ 'function' => array('class' => 'Permalink_Manager_Tools', 'method' => 'regenerate_slugs_output')
24
+ )
25
+ )
26
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
+ return $admin_sections;
29
+ }
30
+
31
+ public function display_instructions() {
32
+ return wpautop(__('<strong>A MySQL backup is highly recommended before using "<em>Custom & native slugs (post names)</em>" mode!</strong>.', 'permalink-manager'));
33
+ }
34
+
35
+ public function find_and_replace_output() {
36
+ // Get all registered post types array & statuses
37
+ $all_post_statuses_array = get_post_statuses();
38
+ $all_post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
39
+
40
+ $fields = array(
41
+ 'old_string' => array(
42
+ 'label' => __( 'Find ...', 'permalink-manager' ),
43
+ 'type' => 'text',
44
+ 'container' => 'row',
45
+ 'container_class' => 'column column-1_2',
46
+ 'input_class' => 'widefat'
47
+ ),
48
+ 'new_string' => array(
49
+ 'label' => __( 'Replace with ...', 'permalink-manager' ),
50
+ 'type' => 'text',
51
+ 'container' => 'row',
52
+ 'container_class' => 'column column-1_2',
53
+ 'input_class' => 'widefat'
54
+ ),
55
  'mode' => array(
56
  'label' => __( 'Select mode', 'permalink-manager' ),
57
  'type' => 'select',
58
+ 'container' => 'row',
59
  'choices' => array('both' => '<strong>' . __('Full URIs', 'permalink-manager') . '</strong>', 'slugs' => '<strong>' . __('Only custom slugs', 'permalink-manager') . '</strong>', 'post_names' => '<strong>' . __('Custom & native slugs (post names)', 'permalink-manager') . '</strong>'),
60
  'default' => array('both'),
61
  ),
62
+ 'post_types' => array(
63
  'label' => __( 'Filter by post types', 'permalink-manager' ),
64
  'type' => 'checkbox',
65
+ 'container' => 'row',
66
+ 'default' => array('post', 'page'),
67
  'choices' => $all_post_types,
68
+ 'select_all' => '',
69
+ 'unselect_all' => '',
70
  ),
71
  'post_statuses' => array(
72
  'label' => __( 'Filter by post statuses', 'permalink-manager' ),
73
  'type' => 'checkbox',
74
+ 'container' => 'row',
75
+ 'default' => array('publish'),
76
  'choices' => $all_post_statuses_array,
77
+ 'select_all' => '',
78
+ 'unselect_all' => '',
79
  )
80
  );
81
 
82
+ $sidebar = '<h3>' . __('Important notices', 'permalink-manager') . '</h3>';
83
+ $sidebar .= self::display_instructions();
84
 
85
+ $output = Permalink_Manager_Admin_Functions::get_the_form($fields, 'columns-3', array('text' => __( 'Find and replace', 'permalink-manager' ), 'class' => 'primary margin-top'), $sidebar, array('action' => 'permalink-manager', 'name' => 'find_and_replace'));
86
 
87
+ return $output;
88
+ }
89
 
90
+ public function regenerate_slugs_output() {
91
+ // Get all registered post types array & statuses
92
+ $all_post_statuses_array = get_post_statuses();
93
+ $all_post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
94
 
95
+ $fields = array(
96
  'mode' => array(
97
  'label' => __( 'Select mode', 'permalink-manager' ),
98
  'type' => 'select',
99
+ 'container' => 'row',
100
  'choices' => array('both' => '<strong>' . __('Full URIs', 'permalink-manager') . '</strong>', 'slugs' => '<strong>' . __('Only custom slugs', 'permalink-manager') . '</strong>', 'post_names' => '<strong>' . __('Custom & native slugs (post names)', 'permalink-manager') . '</strong>'),
101
  ),
102
  'post_types' => array(
103
  'label' => __( 'Filter by post types', 'permalink-manager' ),
104
  'type' => 'checkbox',
105
+ 'container' => 'row',
106
+ 'default' => array('post', 'page'),
107
  'choices' => $all_post_types,
108
+ 'select_all' => '',
109
+ 'unselect_all' => '',
110
  ),
111
  'post_statuses' => array(
112
  'label' => __( 'Filter by post statuses', 'permalink-manager' ),
113
  'type' => 'checkbox',
114
+ 'container' => 'row',
115
+ 'default' => array('publish'),
116
  'choices' => $all_post_statuses_array,
117
+ 'select_all' => '',
118
+ 'unselect_all' => '',
119
  )
120
  );
121
 
122
+ $sidebar = '<h3>' . __('Important notices', 'permalink-manager') . '</h3>';
123
+ $sidebar .= self::display_instructions();
124
+ $output = Permalink_Manager_Admin_Functions::get_the_form($fields, 'columns-3', array('text' => __( 'Regenerate', 'permalink-manager' ), 'class' => 'primary margin-top'), $sidebar, array('action' => 'permalink-manager', 'name' => 'regenerate'));
 
 
 
125
 
126
+ return $output;
127
+ }
128
  }
includes/views/permalink-manager-uri-editor-post.php ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Extend WP_List_Table with two subclasses for post types and taxonomies
5
+ */
6
+ class Permalink_Manager_URI_Editor_Post extends WP_List_Table {
7
+
8
+ public function __construct() {
9
+ global $status, $page;
10
+
11
+ parent::__construct(array(
12
+ 'singular' => 'slug',
13
+ 'plural' => 'slugs'
14
+ ));
15
+ }
16
+
17
+ /**
18
+ * Get the HTML output with the WP_List_Table
19
+ */
20
+ public function display_admin_section() {
21
+ global $wpdb;
22
+
23
+ $output = "<form id=\"permalinks-post-types-table\" class=\"slugs-table\" method=\"post\">";
24
+ $output .= wp_nonce_field('permalink-manager', 'uri_editor', true, true);
25
+
26
+ // Bypass
27
+ ob_start();
28
+
29
+ $this->prepare_items();
30
+ $this->display();
31
+ $output .= ob_get_contents();
32
+
33
+ ob_end_clean();
34
+
35
+ $output .= "</form>";
36
+
37
+ return $output;
38
+ }
39
+
40
+ /**
41
+ * Override the parent columns method. Defines the columns to use in your listing table
42
+ */
43
+ public function get_columns() {
44
+ $columns = array(
45
+ //'cb' => '<input type="checkbox" />', //Render a checkbox instead of text
46
+ 'post_title' => __('Post title', 'permalink-manager'),
47
+ 'post_name' => __('Post name (native slug)', 'permalink-manager'),
48
+ //'post_date_gmt' => __('Date', 'permalink-manager'),
49
+ 'uri' => __('Full URI & Permalink', 'permalink-manager'),
50
+ 'post_status' => __('Post status', 'permalink-manager'),
51
+ );
52
+
53
+ // Additional function when WPML is enabled
54
+ if(class_exists('SitePress')) {
55
+ $columns['post_lang'] = __('Language', 'permalink_manager');
56
+ }
57
+
58
+ return $columns;
59
+ }
60
+
61
+ /**
62
+ * Hidden columns
63
+ */
64
+ public function get_hidden_columns() {
65
+ return array('post_date_gmt');
66
+ }
67
+
68
+ /**
69
+ * Sortable columns
70
+ */
71
+ public function get_sortable_columns() {
72
+ return array(
73
+ 'post_title' => array('post_title', false),
74
+ 'post_name' => array('post_name', false),
75
+ 'post_status' => array('post_status', false),
76
+ );
77
+ }
78
+
79
+ /**
80
+ * Data inside the columns
81
+ */
82
+ public function column_default( $item, $column_name ) {
83
+ $uri = Permalink_Manager_URI_Functions_Post::get_post_uri($item['ID'], true);
84
+ $field_args_base = array('type' => 'text', 'value' => $uri, 'without_label' => true, 'input_class' => '');
85
+ $permalink = get_permalink($item['ID']);
86
+
87
+ switch( $column_name ) {
88
+ case 'post_status':
89
+ $post_statuses_array = get_post_statuses();
90
+ return "<span title=\"{$item[$column_name]}\">{$post_statuses_array[$item[$column_name]]}</span>";
91
+
92
+ case 'post_name':
93
+ $output = $item[ 'post_name' ];
94
+ return $output;
95
+
96
+ case 'uri':
97
+ $output = ($item['post_status'] != 'publish') ? '-' : Permalink_Manager_Admin_Functions::generate_option_field("uri[{$item['ID']}]", $field_args_base);
98
+ $output .= "<a class=\"small post_permalink\" href=\"{$permalink}\" target=\"_blank\"><span class=\"dashicons dashicons-admin-links\"></span> {$permalink}</a>";
99
+ return $output;;
100
+
101
+ case 'post_title':
102
+ $output = $item[ 'post_title' ];
103
+ $output .= '<div class="row-actions">';
104
+ $output .= '<span class="edit"><a target="_blank" href="' . home_url() . '/wp-admin/post.php?post=' . $item[ 'ID' ] . '&amp;action=edit" title="' . __('Edit', 'permalink-manager') . '">' . __('Edit', 'permalink-manager') . '</a> | </span>';
105
+ $output .= '<span class="view"><a target="_blank" href="' . $permalink . '" title="' . __('View', 'permalink-manager') . ' ' . $item[ 'post_title' ] . '" rel="permalink">' . __('View', 'permalink-manager') . '</a> | </span>';
106
+ $output .= '<span class="id">#' . $item[ 'ID' ] . '</span>';
107
+ $output .= '</div>';
108
+ return $output;
109
+
110
+ case 'post_lang':
111
+ $post_lang_details = apply_filters('wpml_post_language_details', NULL, $item['ID']);
112
+ return (!empty($post_lang_details['native_name'])) ? $post_lang_details['native_name'] : "-";
113
+
114
+ default:
115
+ return $item[$column_name];
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Sort the data
121
+ */
122
+ private function sort_data( $a, $b ) {
123
+ // Set defaults
124
+ $orderby = (!empty($_GET['orderby'])) ? $_GET['orderby'] : 'post_title';
125
+ $order = (!empty($_GET['order'])) ? $_GET['order'] : 'asc';
126
+ $result = strnatcasecmp( $a[$orderby], $b[$orderby] );
127
+
128
+ return ($order === 'asc') ? $result : -$result;
129
+ }
130
+
131
+ /**
132
+ * The button that allows to save updated slugs
133
+ */
134
+ function extra_tablenav( $which ) {
135
+ $button_top = __( 'Update all the URIs below', 'permalink-manager' );
136
+ $button_bottom = __( 'Update all the URIs above', 'permalink-manager' );
137
+
138
+ echo '<div class="alignleft actions">';
139
+ submit_button( ${"button_$which"}, 'primary', "update_all_slugs[{$which}]", false, array( 'id' => 'doaction', 'value' => 'update_all_slugs' ) );
140
+ echo '</div>';
141
+ }
142
+
143
+ /**
144
+ * Prepare the items for the table to process
145
+ */
146
+ public function prepare_items() {
147
+ global $wpdb, $permalink_manager_options, $active_subsection;
148
+
149
+ $columns = $this->get_columns();
150
+ $hidden = $this->get_hidden_columns();
151
+ $sortable = $this->get_sortable_columns();
152
+ $current_page = $this->get_pagenum();
153
+
154
+ // Get query variables
155
+ $per_page = $permalink_manager_options['screen-options']['per_page'];
156
+ $post_types_array = $permalink_manager_options['screen-options']['post_types'];
157
+ $post_types = ($active_subsection && $active_subsection == 'all') ? "'" . implode("', '", $post_types_array) . "'" : "'{$active_subsection}'" ;
158
+ $post_statuses_array = $permalink_manager_options['screen-options']['post_statuses'];
159
+ $post_statuses = "'" . implode("', '", $post_statuses_array) . "'";
160
+
161
+ // SQL query parameters
162
+ $order = (isset($_REQUEST['order']) && in_array($_REQUEST['order'], array('asc', 'desc'))) ? $_REQUEST['order'] : 'desc';
163
+ $orderby = (isset($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : 'ID';
164
+ $offset = ($current_page - 1) * $per_page;
165
+
166
+ // Grab posts from database
167
+ //$sql_query = "SELECT * FROM {$wpdb->posts} WHERE post_status IN ($post_statuses) AND post_type IN ($post_types) ORDER BY $orderby $order LIMIT $per_page OFFSET $offset";
168
+ $sql_query = "SELECT * FROM {$wpdb->posts} WHERE post_status IN ($post_statuses) AND post_type IN ($post_types) ORDER BY $orderby $order";
169
+ $all_data = $wpdb->get_results($sql_query, ARRAY_A);
170
+
171
+ // How many items?
172
+ $total_items = $wpdb->num_rows;
173
+
174
+ // Sort posts and count all posts
175
+ usort( $all_data, array( &$this, 'sort_data' ) );
176
+
177
+ $data = array_slice($all_data, $offset, $per_page);
178
+
179
+ // Debug SQL query
180
+ $debug_txt = "<textarea style=\"width:100%;height:300px\">{$sql_query} \n\nOffset: {$offset} \nPage: {$current_page}\nPer page: {$per_page} \nTotal: {$total_items}</textarea>";
181
+ if(isset($_REQUEST['debug_editor_sql'])) { wp_die($debug_txt); }
182
+
183
+ $this->set_pagination_args( array(
184
+ 'total_items' => $total_items,
185
+ 'per_page' => $per_page
186
+ ));
187
+
188
+ $this->_column_headers = array($columns, $hidden, $sortable);
189
+ $this->items = $data;
190
+ }
191
+
192
+ }
includes/views/permalink-manager-uri-editor.php CHANGED
@@ -1,214 +1,65 @@
1
  <?php
2
 
3
  /**
4
- * Display slug editor for Posts, Pages & Custom Post Types
5
- */
6
- class Permalink_Manager_Uri_Editor extends Permalink_Manager_Class {
7
 
8
- public function __construct() {
9
- add_filter( 'permalink-manager-sections', array($this, 'add_admin_section'), 1 );
10
- }
11
-
12
- /**
13
- * Add the section to the Permalink Manager admin page
14
- */
15
- public function add_admin_section($admin_sections) {
16
- global $permalink_manager_options;
17
-
18
- $admin_sections['slug_editor'] = array(
19
- 'name' => __('Permalink editor', 'permalink-manager'),
20
- 'function' => array('class' => 'Permalink_Manager_Uri_Editor_Table', 'method' => 'display_admin_section')
21
- );
22
-
23
- // Display separate section for each post type
24
- $post_types = Permalink_Manager_Helper_Functions::get_post_types_array('full');
25
- foreach($permalink_manager_options['screen-options']['post_types'] as $post_type) {
26
- $admin_sections['slug_editor']['subsections'][$post_type] = array(
27
- 'name' => $post_types[$post_type]['label']
28
- );
29
- }
30
-
31
- return $admin_sections;
32
- }
33
-
34
- }
35
-
36
- class Permalink_Manager_Uri_Editor_Table extends WP_List_Table {
37
-
38
- public function __construct() {
39
- global $status, $page;
40
-
41
- parent::__construct(array(
42
- 'singular' => 'slug',
43
- 'plural' => 'slugs'
44
- ));
45
- }
46
-
47
- /**
48
- * Get the HTML output with the WP_List_Table
49
- */
50
- public function display_admin_section() {
51
- global $wpdb;
52
-
53
- $output = "<form id=\"permalinks-post-types-table\" class=\"slugs-table\" method=\"post\">";
54
- $output .= wp_nonce_field('uri_actions', 'slug_editor', true, true);
55
-
56
- // Bypass
57
- ob_start();
58
-
59
- $this->prepare_items();
60
- $this->display();
61
- $output .= ob_get_contents();
62
-
63
- ob_end_clean();
64
-
65
- $output .= "</form>";
66
-
67
- return $output;
68
- }
69
-
70
- /**
71
- * Override the parent columns method. Defines the columns to use in your listing table
72
- */
73
- public function get_columns() {
74
- $columns = array(
75
- //'cb' => '<input type="checkbox" />', //Render a checkbox instead of text
76
- 'post_title' => __('Post title', 'permalink-manager'),
77
- 'post_name' => __('Post name (native slug)', 'permalink-manager'),
78
- //'post_date_gmt' => __('Date', 'permalink-manager'),
79
- 'uri' => __('Full URI & Permalink', 'permalink-manager'),
80
- 'post_status' => __('Post status', 'permalink-manager'),
81
- );
82
-
83
- return $columns;
84
  }
85
 
86
  /**
87
- * Hidden columns
88
- */
89
- public function get_hidden_columns() {
90
- return array('post_date_gmt');
91
- }
92
 
93
- /**
94
- * Sortable columns
95
- */
96
- public function get_sortable_columns() {
97
- return array(
98
- 'post_title' => array('post_title', false),
99
- 'post_name' => array('post_name', false),
100
- 'post_status' => array('post_status', false),
101
  );
102
- }
103
-
104
- /**
105
- * Data inside the columns
106
- */
107
- public function column_default( $item, $column_name ) {
108
-
109
- $base = Permalink_Manager_Post_URI_Functions::get_post_uri($item[ 'ID' ], false, false);
110
- $field_args_base = array('type' => 'text', 'value' => $base, 'without_label' => true, 'input_class' => '');
111
- $permalink = Permalink_Manager_Post_URI_Functions::get_correct_permalink($item['ID']);
112
-
113
- switch( $column_name ) {
114
- case 'post_status':
115
- $post_statuses_array = get_post_statuses();
116
- return "<span title=\"{$item[$column_name]}\">{$post_statuses_array[$item[$column_name]]}</span>";
117
-
118
- case 'post_name':
119
- $output = $item[ 'post_name' ];
120
- return $output;
121
 
122
- case 'uri':
123
- $output = ($item['post_status'] != 'publish') ? '-' : Permalink_Manager_Admin_Functions::generate_option_field("uri[{$item['ID']}]", $field_args_base);
124
- $output .= "<a class=\"small post_permalink\" href=\"{$permalink}\" target=\"_blank\"><span class=\"dashicons dashicons-admin-links\"></span> {$permalink}</a>";
125
- return $output;;
 
126
 
127
- case 'post_title':
128
- $output = $item[ 'post_title' ];
129
- $output .= '<div class="row-actions">';
130
- $output .= '<span class="edit"><a target="_blank" href="' . home_url() . '/wp-admin/post.php?post=' . $item[ 'ID' ] . '&amp;action=edit" title="' . __('Edit', 'permalink-manager') . '">' . __('Edit', 'permalink-manager') . '</a> | </span>';
131
- $output .= '<span class="view"><a target="_blank" href="' . $permalink . '" title="' . __('View', 'permalink-manager') . ' ' . $item[ 'post_title' ] . '" rel="permalink">' . __('View', 'permalink-manager') . '</a> | </span>';
132
- $output .= '<span class="id">#' . $item[ 'ID' ] . '</span>';
133
- $output .= '</div>';
134
- return $output;
135
 
136
- default:
137
- return $item[ $column_name ];
 
 
138
  }
139
- }
140
-
141
- /**
142
- * Sort the data
143
- */
144
- private function sort_data( $a, $b ) {
145
- // Set defaults
146
- $orderby = (!empty($_GET['orderby'])) ? $_GET['orderby'] : 'post_title';
147
- $order = (!empty($_GET['order'])) ? $_GET['order'] : 'asc';
148
- $result = strnatcasecmp( $a[$orderby], $b[$orderby] );
149
 
150
- return ($order === 'asc') ? $result : -$result;
151
- }
152
-
153
- /**
154
- * The button that allows to save updated slugs
155
- */
156
- function extra_tablenav( $which ) {
157
- $button_top = __( 'Update all the URIs below', 'permalink-manager' );
158
- $button_bottom = __( 'Update all the URIs above', 'permalink-manager' );
159
-
160
- echo '<div class="alignleft actions">';
161
- submit_button( ${"button_$which"}, 'primary', "update_all_slugs[{$which}]", false, array( 'id' => 'doaction', 'value' => 'update_all_slugs' ) );
162
- echo '</div>';
163
- }
164
-
165
- /**
166
- * Prepare the items for the table to process
167
- */
168
- public function prepare_items() {
169
- global $wpdb, $permalink_manager_options, $active_subsection;
170
-
171
- $columns = $this->get_columns();
172
- $hidden = $this->get_hidden_columns();
173
- $sortable = $this->get_sortable_columns();
174
- $current_page = $this->get_pagenum();
175
-
176
- // Get query variables
177
- $per_page = $permalink_manager_options['screen-options']['per_page'];
178
- $post_types_array = $permalink_manager_options['screen-options']['post_types'];
179
- $post_types = ($active_subsection && $active_subsection != 'all') ? "'{$active_subsection}'" : "'" . implode("', '", $post_types_array) . "'";
180
- $post_statuses_array = $permalink_manager_options['screen-options']['post_statuses'];;
181
- $post_statuses = "'" . implode("', '", $post_statuses_array) . "'";
182
-
183
- // Will be used in pagination settings
184
- $total_items = $wpdb->get_var("SELECT COUNT(id) FROM {$wpdb->posts} WHERE post_status IN ($post_statuses) AND post_type IN ($post_types)");
185
-
186
- // SQL query parameters
187
- $order = (isset($_REQUEST['order']) && in_array($_REQUEST['order'], array('asc', 'desc'))) ? $_REQUEST['order'] : 'desc';
188
- $orderby = (isset($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : 'ID';
189
- $offset = ($current_page - 1) * $per_page;
190
-
191
- // Grab posts from database
192
- //$sql_query = "SELECT * FROM {$wpdb->posts} WHERE post_status IN ($post_statuses) AND post_type IN ($post_types) ORDER BY $orderby $order LIMIT $per_page OFFSET $offset";
193
- $sql_query = "SELECT * FROM {$wpdb->posts} WHERE post_status IN ($post_statuses) AND post_type IN ($post_types) ORDER BY $orderby $order";
194
- $all_data = $wpdb->get_results($sql_query, ARRAY_A);
195
-
196
- // Sort posts and count all posts
197
- usort( $all_data, array( &$this, 'sort_data' ) );
198
-
199
- $data = array_slice($all_data, $offset, $per_page);
200
-
201
- // Debug SQL query
202
- $debug_txt = "<textarea style=\"width:100%;height:300px\">{$sql_query} \n\nOffset: {$offset} \nPage: {$current_page}\nPer page: {$per_page} \nTotal: {$total_items}</textarea>";
203
- if(isset($_REQUEST['debug_editor_sql'])) { wp_die($debug_txt); }
204
-
205
- $this->set_pagination_args( array(
206
- 'total_items' => $total_items,
207
- 'per_page' => $per_page
208
- ));
209
 
210
- $this->_column_headers = array($columns, $hidden, $sortable);
211
- $this->items = $data;
212
  }
213
 
214
  }
1
  <?php
2
 
3
  /**
4
+ * Display slug editor for Posts, Pages & Custom Post Types
5
+ */
6
+ class Permalink_Manager_Uri_Editor extends Permalink_Manager_Class {
7
 
8
+ public function __construct() {
9
+ add_filter( 'permalink-manager-sections', array($this, 'add_admin_section'), 1 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  }
11
 
12
  /**
13
+ * Add the section to the Permalink Manager admin page
14
+ */
15
+ public function add_admin_section($admin_sections) {
16
+ global $permalink_manager_options;
 
17
 
18
+ $admin_sections['slug_editor'] = array(
19
+ 'name' => __('Permalink editor', 'permalink-manager')
 
 
 
 
 
 
20
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
+ // Display separate section for each post type
23
+ $post_types = Permalink_Manager_Helper_Functions::get_post_types_array('full');
24
+ foreach($post_types as $post_type_name => $post_type) {
25
+ // Check if post type exists
26
+ if(!post_type_exists($post_type_name)) { continue; }
27
 
28
+ $icon = (class_exists('WooCommerce') && in_array($post_type_name, array('product'))) ? "<i class=\"woocommerce-icon woocommerce-cart\"></i>" : "";
 
 
 
 
 
 
 
29
 
30
+ $admin_sections['slug_editor']['subsections'][$post_type_name] = array(
31
+ 'name' => "{$icon} {$post_type['label']}",
32
+ 'function' => array('class' => 'Permalink_Manager_URI_Editor_Post', 'method' => 'display_admin_section')
33
+ );
34
  }
 
 
 
 
 
 
 
 
 
 
35
 
36
+ // Permalink Manager Pro: Display separate section for each taxonomy
37
+ /* $taxonomies = Permalink_Manager_Helper_Functions::get_taxonomies_array('full');
38
+ foreach($taxonomies as $taxonomy_name => $taxonomy) {
39
+ // Check if taxonomy exists
40
+ if(!taxonomy_exists($taxonomy_name)) { continue; }
41
+
42
+ // Get the icon
43
+ $icon = (class_exists('WooCommerce') && in_array($taxonomy_name, array('product_tag', 'product_cat'))) ? "<i class=\"woocommerce-icon woocommerce-cart\"></i>" : "<i class=\"dashicons dashicons-tag\"></i>";
44
+
45
+ $admin_sections['slug_editor']['subsections']["tax_{$taxonomy_name}"] = array(
46
+ 'name' => "{$icon} {$taxonomy['label']}",
47
+ 'html' => Permalink_Manager_Admin_Functions::pro_text(),
48
+ 'pro' => true
49
+ );
50
+ } */
51
+
52
+ // A little dirty hack to move wooCommerce product & taxonomies to the end of array
53
+ if(class_exists('WooCommerce')) {
54
+ foreach(array('product', 'tax_product_tag', 'tax_product_cat') as $section_name) {
55
+ if(empty($admin_sections['slug_editor']['subsections'][$section_name])) { continue; }
56
+ $section = $admin_sections['slug_editor']['subsections'][$section_name];
57
+ unset($admin_sections['slug_editor']['subsections'][$section_name]);
58
+ $admin_sections['slug_editor']['subsections'][$section_name] = $section;
59
+ }
60
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
+ return $admin_sections;
 
63
  }
64
 
65
  }
js/permalink-manager-admin.js DELETED
@@ -1,35 +0,0 @@
1
- jQuery(document).ready(function() {
2
-
3
- /*
4
- * Tab navigation
5
- */
6
- /*jQuery('#permalink-manager-tabs-nav a').on('click', function(){
7
-
8
- // Disable current active tab in navigation
9
- jQuery('#permalink-manager-tabs-nav .nav-tab-active').removeClass('nav-tab-active');
10
- jQuery('#permalink-manager-tabs .show').removeClass('show');
11
-
12
- // Get current tab name
13
- var tab_to_open = jQuery(this).data("tab");
14
-
15
- // Add "active" class to the clicked tab
16
- jQuery(this).addClass('nav-tab-active');
17
- jQuery('#permalink-manager-tabs div[data-tab="'+tab_to_open+'"]').addClass('show');
18
-
19
- // Disable native click event
20
- return false;
21
- });*/
22
-
23
- /*
24
- * "Select all" checkbox
25
- */
26
- jQuery('input[value="all"]').on('change', function() {
27
- // Uncheck "Select all"
28
- jQuery(this).prop('checked', false);
29
-
30
- jQuery(this).parents('.checkboxes').find('input[type="checkbox"]').not(this).each(function() {
31
- jQuery(this).prop('checked', true);
32
- });
33
- });
34
-
35
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/permalink-manager.pot CHANGED
@@ -1,286 +1,223 @@
1
- # Copyright (C) 2017 Permalink Manager
2
- # This file is distributed under the same license as the Permalink Manager package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Permalink Manager 0.5.1\n"
6
- "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/permalink-"
7
- "manager\n"
8
- "POT-Creation-Date: 2017-02-06 20:18:19+00:00\n"
 
 
 
 
 
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "PO-Revision-Date: 2017-MO-DA HO:MI+ZONE\n"
13
- "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
- "Language-Team: LANGUAGE <LL@li.org>\n"
15
-
16
- #: inc/permalink-manager-base-editor.php:27
17
- #: inc/permalink-manager-editor.php:32
18
- msgid "Post Type"
19
- msgstr ""
20
-
21
- #: inc/permalink-manager-base-editor.php:28
22
- msgid "Custom Permalink Base/Permastruct"
23
- msgstr ""
24
-
25
- #: inc/permalink-manager-base-editor.php:87
26
- #: includes/views/permalink-manager-settings.php:110
27
- msgid "Save settings"
28
- msgstr ""
29
-
30
- #: inc/permalink-manager-editor.php:27
31
- #: includes/core/permalink-manager-admin-functions.php:454
32
- #: includes/core/permalink-manager-admin-functions.php:470
33
- msgid "Title"
34
- msgstr ""
35
-
36
- #: inc/permalink-manager-editor.php:28
37
- msgid "Post Name (Native Slug)"
38
- msgstr ""
39
-
40
- #: inc/permalink-manager-editor.php:30
41
- msgid "Base & Slug (URI)"
42
- msgstr ""
43
-
44
- #: inc/permalink-manager-editor.php:31
45
- msgid "Post Status"
46
- msgstr ""
47
-
48
- #: inc/permalink-manager-editor.php:84
49
- #: includes/views/permalink-manager-uri-editor.php:130
50
- msgid "Edit"
51
- msgstr ""
52
-
53
- #: inc/permalink-manager-editor.php:85
54
- #: includes/views/permalink-manager-uri-editor.php:131
55
- msgid "View"
56
- msgstr ""
57
-
58
- #: inc/permalink-manager-editor.php:111
59
- msgid "Update all slugs below"
60
- msgstr ""
61
 
62
- #: inc/permalink-manager-editor.php:112
63
- msgid "Update all slugs above"
 
64
  msgstr ""
65
 
66
- #: inc/permalink-manager-screen-options.php:22
67
- msgid "Apply"
68
  msgstr ""
69
 
70
- #. #-#-#-#-# plugin.pot (Permalink Manager 0.5.1) #-#-#-#-#
71
- #. Plugin Name of the plugin/theme
72
- #: includes/core/permalink-manager-admin-functions.php:114
73
  msgid "Permalink Manager"
74
  msgstr ""
75
 
76
- #: includes/core/permalink-manager-admin-functions.php:146
77
  msgid "Go To Permalink Manager"
78
  msgstr ""
79
 
80
- #: includes/core/permalink-manager-admin-functions.php:199
81
  msgid "Select all"
82
  msgstr ""
83
 
84
- #: includes/core/permalink-manager-admin-functions.php:200
85
  msgid "Unselect all"
86
  msgstr ""
87
 
88
- #: includes/core/permalink-manager-admin-functions.php:379
89
  msgid "by Maciej Bis"
90
  msgstr ""
91
 
92
- #: includes/core/permalink-manager-admin-functions.php:455
93
- #: includes/core/permalink-manager-admin-functions.php:471
 
 
 
 
 
94
  msgid "Old URI"
95
  msgstr ""
96
 
97
- #: includes/core/permalink-manager-admin-functions.php:456
98
- #: includes/core/permalink-manager-admin-functions.php:472
99
  msgid "New URI"
100
  msgstr ""
101
 
102
- #: includes/core/permalink-manager-admin-functions.php:457
103
- #: includes/core/permalink-manager-admin-functions.php:473
104
  msgid "Old Slug"
105
  msgstr ""
106
 
107
- #: includes/core/permalink-manager-admin-functions.php:458
108
- #: includes/core/permalink-manager-admin-functions.php:474
109
  msgid "New Slug"
110
  msgstr ""
111
 
112
- #: includes/core/permalink-manager-admin-functions.php:470
113
  msgid "Show more details"
114
  msgstr ""
115
 
116
- #: includes/core/permalink-manager-admin-functions.php:479
117
  msgid "List of updated items"
118
  msgstr ""
119
 
120
- #: includes/core/permalink-manager-uri-actions.php:46
121
- msgid "<strong>%d</strong> slug was updated!"
122
- msgid_plural "<strong>%d</strong> slugs were updated!"
123
- msgstr[0] ""
124
- msgstr[1] ""
125
-
126
- #: includes/core/permalink-manager-uri-actions.php:47
127
- msgid "<a href=\"%s\">Click here</a> to go to the list of updated slugs"
128
- msgstr ""
129
-
130
- #: includes/core/permalink-manager-uri-actions.php:52
131
- msgid "<strong>No slugs</strong> were updated!"
132
- msgstr ""
133
-
134
- #: includes/views/permalink-manager-advanced.php:14
135
- msgid "Advanced"
136
- msgstr ""
137
-
138
- #: includes/views/permalink-manager-advanced.php:31
139
- msgid "Debug data"
140
- msgstr ""
141
-
142
- #: includes/views/permalink-manager-advanced.php:35
143
- msgid "List of the URIs generated by this plugin."
144
- msgstr ""
145
-
146
- #: includes/views/permalink-manager-advanced.php:36
147
- msgid "Array with URIs"
148
  msgstr ""
149
 
150
- #: includes/views/permalink-manager-advanced.php:42
151
- msgid "List of the permastructures."
152
  msgstr ""
153
 
154
- #: includes/views/permalink-manager-advanced.php:43
155
- msgid "Array with permastructures"
156
  msgstr ""
157
 
158
- #: includes/views/permalink-manager-advanced.php:49
159
- msgid "Currently used plugin settings."
160
  msgstr ""
161
 
162
- #: includes/views/permalink-manager-advanced.php:50
163
- msgid "Array with settings used in this plugin."
164
  msgstr ""
165
 
166
- #: includes/views/permalink-manager-advanced.php:56
167
- msgid "Permalink hooks."
 
168
  msgstr ""
169
 
170
- #: includes/views/permalink-manager-advanced.php:57
171
- msgid "Array with list of permalink hooks used on this website."
172
  msgstr ""
173
 
174
- #: includes/views/permalink-manager-permastructs.php:15
175
- msgid "Permastructures"
176
  msgstr ""
177
 
178
- #: includes/views/permalink-manager-permastructs.php:48
179
- msgid ""
180
- "All available <a href=\"%s\" target=\"_blank\">structure tags</a> allowed "
181
- "are listed below. Please note that some of them can be used only for "
182
- "particular post types."
183
  msgstr ""
184
 
185
- #: includes/views/permalink-manager-permastructs.php:49
186
- msgid "Each Custom Post Type should have unique permastructure."
 
 
187
  msgstr ""
188
 
189
- #: includes/views/permalink-manager-permastructs.php:50
190
  msgid ""
191
- "Please note that the following settings will be applied only to new posts."
192
- "<br />If you would like to use the current permastructures settings, you "
193
- "will need to regenerate the posts' URIs in <strong>\"Tools -> Regnerate/Reset"
194
- "\"</strong> section."
195
- msgstr ""
196
-
197
- #: includes/views/permalink-manager-permastructs.php:51
198
- msgid "To use the native permastruct please keep the field empty."
199
- msgstr ""
200
-
201
- #: includes/views/permalink-manager-permastructs.php:52
202
- msgid "Usage Instructions"
203
  msgstr ""
204
 
205
- #: includes/views/permalink-manager-permastructs.php:55
206
- msgid "Save permastructures"
207
  msgstr ""
208
 
209
- #: includes/views/permalink-manager-settings.php:15
210
- msgid "Settings"
211
  msgstr ""
212
 
213
- #: includes/views/permalink-manager-settings.php:58
214
- msgid "Display settings"
215
  msgstr ""
216
 
217
- #: includes/views/permalink-manager-settings.php:59
218
- msgid "Adjust the data displayed in \"Permalink Editor\" section."
 
 
 
219
  msgstr ""
220
 
221
- #: includes/views/permalink-manager-settings.php:63
222
- msgid "Per page"
223
  msgstr ""
224
 
225
- #: includes/views/permalink-manager-settings.php:68
226
- msgid "Post statuses"
 
227
  msgstr ""
228
 
229
- #: includes/views/permalink-manager-settings.php:75
230
- msgid "Post types"
231
  msgstr ""
232
 
233
- #: includes/views/permalink-manager-settings.php:83
234
- msgid "Miscellaneous & SEO functions"
235
  msgstr ""
236
 
237
- #: includes/views/permalink-manager-settings.php:87
238
- msgid "Primay term/category support"
239
  msgstr ""
240
 
241
- #: includes/views/permalink-manager-settings.php:89
242
- #: includes/views/permalink-manager-settings.php:103
243
- msgid "Enable"
244
  msgstr ""
245
 
246
- #: includes/views/permalink-manager-settings.php:89
247
- #: includes/views/permalink-manager-settings.php:96
248
- #: includes/views/permalink-manager-settings.php:103
249
- msgid "Disable"
250
  msgstr ""
251
 
252
- #: includes/views/permalink-manager-settings.php:90
253
- msgid ""
254
- "Used to generate default permalinks in pages, posts & custom post types. "
255
- "Works only when \"Yoast SEO\" plugin is enabled."
256
  msgstr ""
257
 
258
- #: includes/views/permalink-manager-settings.php:94
259
- msgid "Redirect"
260
  msgstr ""
261
 
262
- #: includes/views/permalink-manager-settings.php:96
263
- msgid "Enable \"301 redirect\""
264
  msgstr ""
265
 
266
- #: includes/views/permalink-manager-settings.php:96
267
- msgid "Enable \"302 redirect\""
268
  msgstr ""
269
 
270
- #: includes/views/permalink-manager-settings.php:97
271
- msgid ""
272
- "If enabled - the visitors will be redirected from native permalinks to your "
273
- "custom permalinks. Please note that the redirects will work correctly only "
274
- "if native slug \"post name\" will not be changed."
275
  msgstr ""
276
 
277
- #: includes/views/permalink-manager-settings.php:101
278
- msgid "Canonical redirect"
279
  msgstr ""
280
 
281
- #: includes/views/permalink-manager-settings.php:104
282
- msgid ""
283
- "This function allows Wordpress to correct the URLs used by the visitors."
284
  msgstr ""
285
 
286
  #: includes/views/permalink-manager-tools.php:15
@@ -288,7 +225,7 @@ msgid "Tools"
288
  msgstr ""
289
 
290
  #: includes/views/permalink-manager-tools.php:18
291
- #: includes/views/permalink-manager-tools.php:83
292
  msgid "Find and replace"
293
  msgstr ""
294
 
@@ -298,100 +235,132 @@ msgstr ""
298
 
299
  #: includes/views/permalink-manager-tools.php:32
300
  msgid ""
301
- "<h4>A MySQL backup is highly recommended before using \"<em>Custom & native "
302
- "slugs (post names)</em>\" mode!</h4>With this mode selected, "
303
- "<strong>post_name</strong> field (native slug) will be changed directly in "
304
- "<a href=\"%s\"><strong>\"posts\"</strong></a> database table."
305
  msgstr ""
306
 
307
- #: includes/views/permalink-manager-tools.php:44
308
  msgid "Find ..."
309
  msgstr ""
310
 
311
- #: includes/views/permalink-manager-tools.php:50
312
  msgid "Replace with ..."
313
  msgstr ""
314
 
315
- #: includes/views/permalink-manager-tools.php:57
316
- #: includes/views/permalink-manager-tools.php:95
317
  msgid "Select mode"
318
  msgstr ""
319
 
320
  #: includes/views/permalink-manager-tools.php:59
321
- #: includes/views/permalink-manager-tools.php:97
322
  msgid "Full URIs"
323
  msgstr ""
324
 
325
  #: includes/views/permalink-manager-tools.php:59
326
- #: includes/views/permalink-manager-tools.php:97
327
  msgid "Only custom slugs"
328
  msgstr ""
329
 
330
  #: includes/views/permalink-manager-tools.php:59
331
- #: includes/views/permalink-manager-tools.php:97
332
  msgid "Custom & native slugs (post names)"
333
  msgstr ""
334
 
335
  #: includes/views/permalink-manager-tools.php:63
336
- #: includes/views/permalink-manager-tools.php:100
337
  msgid "Filter by post types"
338
  msgstr ""
339
 
340
- #: includes/views/permalink-manager-tools.php:71
341
- #: includes/views/permalink-manager-tools.php:108
342
  msgid "Filter by post statuses"
343
  msgstr ""
344
 
345
- #: includes/views/permalink-manager-tools.php:80
346
- #: includes/views/permalink-manager-tools.php:117
347
- msgid "Important notes"
348
  msgstr ""
349
 
350
- #: includes/views/permalink-manager-tools.php:119
351
  msgid "Regenerate"
352
  msgstr ""
353
 
354
- #: includes/views/permalink-manager-uri-editor.php:19
355
- msgid "Permalink editor"
356
  msgstr ""
357
 
358
- #: includes/views/permalink-manager-uri-editor.php:76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
359
  msgid "Post title"
360
  msgstr ""
361
 
362
- #: includes/views/permalink-manager-uri-editor.php:77
363
  msgid "Post name (native slug)"
364
  msgstr ""
365
 
366
- #: includes/views/permalink-manager-uri-editor.php:79
367
  msgid "Full URI & Permalink"
368
  msgstr ""
369
 
370
- #: includes/views/permalink-manager-uri-editor.php:80
371
  msgid "Post status"
372
  msgstr ""
373
 
374
- #: includes/views/permalink-manager-uri-editor.php:157
 
 
 
 
 
 
 
 
 
 
375
  msgid "Update all the URIs below"
376
  msgstr ""
377
 
378
- #: includes/views/permalink-manager-uri-editor.php:158
379
  msgid "Update all the URIs above"
380
  msgstr ""
381
 
382
- #. #-#-#-#-# plugin.pot (Permalink Manager 0.5.1) #-#-#-#-#
383
- #. Plugin URI of the plugin/theme
384
- #. #-#-#-#-# plugin.pot (Permalink Manager 0.5.1) #-#-#-#-#
385
- #. Author URI of the plugin/theme
386
- msgid "http://maciejbis.net/"
387
  msgstr ""
388
 
389
- #. Description of the plugin/theme
390
- msgid ""
391
- "A simple tool that allows to mass update of slugs that are used to build "
392
- "permalinks for Posts, Pages and Custom Post Types."
393
  msgstr ""
394
 
395
- #. Author of the plugin/theme
396
  msgid "Maciej Bis"
397
  msgstr ""
1
+ #, fuzzy
 
2
  msgid ""
3
  msgstr ""
4
+ "Project-Id-Version: Permalink Manager\n"
5
+ "Report-Msgid-Bugs-To: \n"
6
+ "POT-Creation-Date: 2017-03-07 02:01+0000\n"
7
+ "POT-Revision-Date: Fri Jan 08 2016 20:08:23 GMT+0100 (CET)\n"
8
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
9
+ "Last-Translator: \n"
10
+ "Language-Team: \n"
11
+ "Language: \n"
12
+ "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION\n"
13
  "MIME-Version: 1.0\n"
14
  "Content-Type: text/plain; charset=UTF-8\n"
15
  "Content-Transfer-Encoding: 8bit\n"
16
+ "X-Poedit-SourceCharset: UTF-8\n"
17
+ "X-Poedit-Basepath: .\n"
18
+ "X-Poedit-SearchPath-0: ..\n"
19
+ "X-Poedit-KeywordsList: _:1;gettext:1;dgettext:2;ngettext:1,2;dngettext:2,3;"
20
+ "__:1;_e:1;_c:1;_n:1,2;_n_noop:1,2;_nc:1,2;__ngettext:1,2;__ngettext_noop:1,2;"
21
+ "_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;"
22
+ "esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;"
23
+ "esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;transChoice:1,2\n"
24
+ "X-Generator: Loco - https://localise.biz/"
25
+
26
+ #: includes/core/permalink-manager-actions.php:50
27
+ #, php-format
28
+ msgid "<strong>%d</strong> slug was updated!"
29
+ msgid_plural "<strong>%d</strong> slugs were updated!"
30
+ msgstr[0] ""
31
+ msgstr[1] ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
+ #: includes/core/permalink-manager-actions.php:51
34
+ #, php-format
35
+ msgid "<a %s>Click here</a> to go to the list of updated slugs"
36
  msgstr ""
37
 
38
+ #: includes/core/permalink-manager-actions.php:56
39
+ msgid "<strong>No slugs</strong> were updated!"
40
  msgstr ""
41
 
42
+ #. Name of the plugin
43
+ #: includes/core/permalink-manager-admin-functions.php:75
44
+ #: includes/core/permalink-manager-admin-functions.php:75
45
  msgid "Permalink Manager"
46
  msgstr ""
47
 
48
+ #: includes/core/permalink-manager-admin-functions.php:107
49
  msgid "Go To Permalink Manager"
50
  msgstr ""
51
 
52
+ #: includes/core/permalink-manager-admin-functions.php:160
53
  msgid "Select all"
54
  msgstr ""
55
 
56
+ #: includes/core/permalink-manager-admin-functions.php:161
57
  msgid "Unselect all"
58
  msgstr ""
59
 
60
+ #: includes/core/permalink-manager-admin-functions.php:337
61
  msgid "by Maciej Bis"
62
  msgstr ""
63
 
64
+ #: includes/core/permalink-manager-admin-functions.php:421
65
+ #: includes/core/permalink-manager-admin-functions.php:437
66
+ msgid "Title"
67
+ msgstr ""
68
+
69
+ #: includes/core/permalink-manager-admin-functions.php:422
70
+ #: includes/core/permalink-manager-admin-functions.php:438
71
  msgid "Old URI"
72
  msgstr ""
73
 
74
+ #: includes/core/permalink-manager-admin-functions.php:423
75
+ #: includes/core/permalink-manager-admin-functions.php:439
76
  msgid "New URI"
77
  msgstr ""
78
 
79
+ #: includes/core/permalink-manager-admin-functions.php:424
80
+ #: includes/core/permalink-manager-admin-functions.php:440
81
  msgid "Old Slug"
82
  msgstr ""
83
 
84
+ #: includes/core/permalink-manager-admin-functions.php:425
85
+ #: includes/core/permalink-manager-admin-functions.php:441
86
  msgid "New Slug"
87
  msgstr ""
88
 
89
+ #: includes/core/permalink-manager-admin-functions.php:437
90
  msgid "Show more details"
91
  msgstr ""
92
 
93
+ #: includes/core/permalink-manager-admin-functions.php:446
94
  msgid "List of updated items"
95
  msgstr ""
96
 
97
+ #: includes/views/permalink-manager-settings.php:15
98
+ msgid "Settings"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  msgstr ""
100
 
101
+ #: includes/views/permalink-manager-settings.php:62
102
+ msgid "Display settings"
103
  msgstr ""
104
 
105
+ #: includes/views/permalink-manager-settings.php:63
106
+ msgid "Adjust the data displayed in \"Permalink Editor\" section."
107
  msgstr ""
108
 
109
+ #: includes/views/permalink-manager-settings.php:68
110
+ msgid "Per page"
111
  msgstr ""
112
 
113
+ #: includes/views/permalink-manager-settings.php:73
114
+ msgid "Post statuses"
115
  msgstr ""
116
 
117
+ #: includes/views/permalink-manager-settings.php:80
118
+ #: includes/views/permalink-manager-permastructs.php:36
119
+ msgid "Post types"
120
  msgstr ""
121
 
122
+ #: includes/views/permalink-manager-settings.php:88
123
+ msgid "Miscellaneous & SEO functions"
124
  msgstr ""
125
 
126
+ #: includes/views/permalink-manager-settings.php:93
127
+ msgid "Primay term/category support"
128
  msgstr ""
129
 
130
+ #: includes/views/permalink-manager-settings.php:95
131
+ #: includes/views/permalink-manager-settings.php:109
132
+ msgid "Enable"
 
 
133
  msgstr ""
134
 
135
+ #: includes/views/permalink-manager-settings.php:95
136
+ #: includes/views/permalink-manager-settings.php:102
137
+ #: includes/views/permalink-manager-settings.php:109
138
+ msgid "Disable"
139
  msgstr ""
140
 
141
+ #: includes/views/permalink-manager-settings.php:96
142
  msgid ""
143
+ "Used to generate default permalinks in pages, posts & custom post types. "
144
+ "Works only when \"Yoast SEO\" plugin is enabled."
 
 
 
 
 
 
 
 
 
 
145
  msgstr ""
146
 
147
+ #: includes/views/permalink-manager-settings.php:100
148
+ msgid "Redirect"
149
  msgstr ""
150
 
151
+ #: includes/views/permalink-manager-settings.php:102
152
+ msgid "Enable \"301 redirect\""
153
  msgstr ""
154
 
155
+ #: includes/views/permalink-manager-settings.php:102
156
+ msgid "Enable \"302 redirect\""
157
  msgstr ""
158
 
159
+ #: includes/views/permalink-manager-settings.php:103
160
+ msgid ""
161
+ "If enabled - the visitors will be redirected from native permalinks to your "
162
+ "custom permalinks. Please note that the redirects will work correctly only "
163
+ "if native slug \"post name\" will not be changed."
164
  msgstr ""
165
 
166
+ #: includes/views/permalink-manager-settings.php:107
167
+ msgid "Canonical redirect"
168
  msgstr ""
169
 
170
+ #: includes/views/permalink-manager-settings.php:110
171
+ msgid ""
172
+ "This function allows Wordpress to correct the URLs used by the visitors."
173
  msgstr ""
174
 
175
+ #: includes/views/permalink-manager-settings.php:116
176
+ msgid "Save settings"
177
  msgstr ""
178
 
179
+ #: includes/views/permalink-manager-advanced.php:14
180
+ msgid "Advanced"
181
  msgstr ""
182
 
183
+ #: includes/views/permalink-manager-advanced.php:31
184
+ msgid "Debug data"
185
  msgstr ""
186
 
187
+ #: includes/views/permalink-manager-advanced.php:35
188
+ msgid "List of the URIs generated by this plugin."
 
189
  msgstr ""
190
 
191
+ #: includes/views/permalink-manager-advanced.php:36
192
+ msgid "Array with URIs"
 
 
193
  msgstr ""
194
 
195
+ #: includes/views/permalink-manager-advanced.php:42
196
+ msgid "List of the permastructures."
 
 
197
  msgstr ""
198
 
199
+ #: includes/views/permalink-manager-advanced.php:43
200
+ msgid "Array with permastructures"
201
  msgstr ""
202
 
203
+ #: includes/views/permalink-manager-advanced.php:49
204
+ msgid "Currently used plugin settings."
205
  msgstr ""
206
 
207
+ #: includes/views/permalink-manager-advanced.php:50
208
+ msgid "Array with settings used in this plugin."
209
  msgstr ""
210
 
211
+ #: includes/views/permalink-manager-advanced.php:56
212
+ msgid "Permalink hooks."
 
 
 
213
  msgstr ""
214
 
215
+ #: includes/views/permalink-manager-advanced.php:57
216
+ msgid "Array with list of permalink hooks used on this website."
217
  msgstr ""
218
 
219
+ #: includes/views/permalink-manager-uri-editor.php:19
220
+ msgid "Permalink editor"
 
221
  msgstr ""
222
 
223
  #: includes/views/permalink-manager-tools.php:15
225
  msgstr ""
226
 
227
  #: includes/views/permalink-manager-tools.php:18
228
+ #: includes/views/permalink-manager-tools.php:85
229
  msgid "Find and replace"
230
  msgstr ""
231
 
235
 
236
  #: includes/views/permalink-manager-tools.php:32
237
  msgid ""
238
+ "<strong>A MySQL backup is highly recommended before using \"<em>Custom & "
239
+ "native slugs (post names)</em>\" mode!</strong>."
 
 
240
  msgstr ""
241
 
242
+ #: includes/views/permalink-manager-tools.php:42
243
  msgid "Find ..."
244
  msgstr ""
245
 
246
+ #: includes/views/permalink-manager-tools.php:49
247
  msgid "Replace with ..."
248
  msgstr ""
249
 
250
+ #: includes/views/permalink-manager-tools.php:56
251
+ #: includes/views/permalink-manager-tools.php:97
252
  msgid "Select mode"
253
  msgstr ""
254
 
255
  #: includes/views/permalink-manager-tools.php:59
256
+ #: includes/views/permalink-manager-tools.php:100
257
  msgid "Full URIs"
258
  msgstr ""
259
 
260
  #: includes/views/permalink-manager-tools.php:59
261
+ #: includes/views/permalink-manager-tools.php:100
262
  msgid "Only custom slugs"
263
  msgstr ""
264
 
265
  #: includes/views/permalink-manager-tools.php:59
266
+ #: includes/views/permalink-manager-tools.php:100
267
  msgid "Custom & native slugs (post names)"
268
  msgstr ""
269
 
270
  #: includes/views/permalink-manager-tools.php:63
271
+ #: includes/views/permalink-manager-tools.php:103
272
  msgid "Filter by post types"
273
  msgstr ""
274
 
275
+ #: includes/views/permalink-manager-tools.php:72
276
+ #: includes/views/permalink-manager-tools.php:112
277
  msgid "Filter by post statuses"
278
  msgstr ""
279
 
280
+ #: includes/views/permalink-manager-tools.php:82
281
+ #: includes/views/permalink-manager-tools.php:122
282
+ msgid "Important notices"
283
  msgstr ""
284
 
285
+ #: includes/views/permalink-manager-tools.php:124
286
  msgid "Regenerate"
287
  msgstr ""
288
 
289
+ #: includes/views/permalink-manager-permastructs.php:15
290
+ msgid "Permastructures"
291
  msgstr ""
292
 
293
+ #: includes/views/permalink-manager-permastructs.php:29
294
+ #, php-format
295
+ msgid ""
296
+ "All available <a href=\"%s\" target=\"_blank\">structure tags</a> for "
297
+ "<strong>post types</strong> allowed are listed below."
298
+ msgstr ""
299
+
300
+ #: includes/views/permalink-manager-permastructs.php:31
301
+ msgid ""
302
+ "Please note that some of them can be used only for particular post types' "
303
+ "settings."
304
+ msgstr ""
305
+
306
+ #: includes/views/permalink-manager-permastructs.php:42
307
+ msgid "Taxonomies"
308
+ msgstr ""
309
+
310
+ #: includes/views/permalink-manager-permastructs.php:52
311
+ msgid "WooCommerce"
312
+ msgstr ""
313
+
314
+ #: includes/views/permalink-manager-permastructs.php:87
315
+ msgid "Save permastructures"
316
+ msgstr ""
317
+
318
+ #: includes/views/permalink-manager-uri-editor-post.php:46
319
  msgid "Post title"
320
  msgstr ""
321
 
322
+ #: includes/views/permalink-manager-uri-editor-post.php:47
323
  msgid "Post name (native slug)"
324
  msgstr ""
325
 
326
+ #: includes/views/permalink-manager-uri-editor-post.php:49
327
  msgid "Full URI & Permalink"
328
  msgstr ""
329
 
330
+ #: includes/views/permalink-manager-uri-editor-post.php:50
331
  msgid "Post status"
332
  msgstr ""
333
 
334
+ #: includes/views/permalink-manager-uri-editor-post.php:104
335
+ #: includes/views/permalink-manager-uri-editor-post.php:104
336
+ msgid "Edit"
337
+ msgstr ""
338
+
339
+ #: includes/views/permalink-manager-uri-editor-post.php:105
340
+ #: includes/views/permalink-manager-uri-editor-post.php:105
341
+ msgid "View"
342
+ msgstr ""
343
+
344
+ #: includes/views/permalink-manager-uri-editor-post.php:135
345
  msgid "Update all the URIs below"
346
  msgstr ""
347
 
348
+ #: includes/views/permalink-manager-uri-editor-post.php:136
349
  msgid "Update all the URIs above"
350
  msgstr ""
351
 
352
+ #. Description of the plugin
353
+ msgid ""
354
+ "Most advanced Permalink utility for Wordpress. It allows to bulk edit the "
355
+ "permalinks & permastructures and regenerate/reset all the URIs in your "
356
+ "Wordpress instance."
357
  msgstr ""
358
 
359
+ #. URI of the plugin
360
+ #. Author URI of the plugin
361
+ msgid "http://maciejbis.net/"
 
362
  msgstr ""
363
 
364
+ #. Author of the plugin
365
  msgid "Maciej Bis"
366
  msgstr ""
out/permalink-manager-admin.css CHANGED
@@ -4,26 +4,37 @@
4
  #permalink-manager #plugin-name-heading a{color:#959595;font-size:60%;text-decoration:none}
5
  #permalink-manager #permalink-manager-tab-nav > a:first-child{margin-left:0}
6
  #permalink-manager h4{font-size:18px;margin-bottom:10px}
 
 
 
7
  #permalink-manager .small{display:block;font-weight:400;color:#888;font-size:80%}
8
  #permalink-manager .settings-select{min-width:200px}
9
  #permalink-manager .fixed-table{max-width:100%;table-layout:fixed}
10
  #permalink-manager .margin-top{margin-top:15px}
11
 
 
 
 
 
12
  #permalink-manager .subsubsub{display:block;width:100%;overflow:hidden;margin-bottom:8px}
13
  #permalink-manager .subsubsub li:before{content:" | "}
14
  #permalink-manager .subsubsub li:first-child:before{content:"";color:#aaa}
 
15
  #permalink-manager .tablenav{margin:15px 0;height:auto}
16
  #permalink-manager .tablenav.top{margin-top:0}
17
  #permalink-manager .tablenav .actions{padding:0;overflow:visible}
18
- #permalink-manager .column-post_type,#permalink-manager .column-post_status{width:13%}
 
 
19
  #permalink-manager .post_name input{max-width:100%}
20
- #permalink-manager .post_permalink a,#permalink-manager .post_permalink .dashicons{font-size:13px;color:#aaa;line-height:1.5em;height:auto;width:auto}
21
  #permalink-manager .post_permalink{margin-top:5px;display:block}
22
 
23
- #permalink-manager .alert{line-height:19px;padding:11px 15px;margin:15px 0}
24
- #permalink-manager .alert p{margin-top:0;line-height:200%}
 
25
  #permalink-manager .alert ul,#permalink-manager .alert ol{margin-top:0;margin-bottom:0}
26
- #permalink-manager .alert p:last-of-type,#permalink-manager .alert li:last-of-type{margin-bottom:0}
27
  #permalink-manager .warning{background:#dc3232}
28
  #permalink-manager .warning,#permalink-manager .warning a{color:#fff}
29
  #permalink-manager .info{background:#f9f9f9}
@@ -35,12 +46,16 @@
35
  #permalink-manager .section-notes ol{margin-top:0;margin-bottom:0}
36
  #permalink-manager .section-notes ol li:last-of-type{margin-bottom:0}
37
  #permalink-manager .short-pre,#permalink-manager .short-textarea{height:150px;overflow:auto;max-width:100%;display:block}
 
38
 
39
  #permalink-manager .checkbox_actions{padding-top:10px;border-top:1px solid #ddd}
40
  #permalink-manager .extra-links{margin-top:5px;font-size:12px}
41
- #permalink-manager .extra-links a{background:#e5e5e5;border:1px solid #ccc;padding:3px 5px;color:#555;display:inline-block;text-decoration:none}
 
 
42
  #permalink-manager .checkboxes{margin-left:-15px;margin-right:15px;overflow:hidden;display:block}
43
  #permalink-manager .checkboxes > label{display:inline-block;width:33%;float:left;padding:0 15px;box-sizing:border-box;padding-bottom:5px}
 
44
  #permalink-manager .field-description{font-size:12px}
45
  #permalink-manager .appended-row td{padding-left:0;padding-right:0}
46
 
@@ -57,5 +72,5 @@
57
  * Breakpoints
58
  */
59
  @media only screen and (max-width : 782px) {
60
- #permalink-manager .columns-container .column-1_2,#permalink-manager .columns-container .column-1_3,#permalink-manager .columns-container .column-2_3{width:100%}
61
  }
4
  #permalink-manager #plugin-name-heading a{color:#959595;font-size:60%;text-decoration:none}
5
  #permalink-manager #permalink-manager-tab-nav > a:first-child{margin-left:0}
6
  #permalink-manager h4{font-size:18px;margin-bottom:10px}
7
+ #permalink-manager h5{font-size:15px;margin-bottom:10px}
8
+ #permalink-manager .structure-tags-list{display:block;line-height:175%}
9
+ #permalink-manager .structure-tags-list code{}
10
  #permalink-manager .small{display:block;font-weight:400;color:#888;font-size:80%}
11
  #permalink-manager .settings-select{min-width:200px}
12
  #permalink-manager .fixed-table{max-width:100%;table-layout:fixed}
13
  #permalink-manager .margin-top{margin-top:15px}
14
 
15
+ #permalink-manager .woocommerce-icon:before{font-family:"WooCommerce";font-style:normal}
16
+ #permalink-manager .woocommerce-cart:before{content:"\e01d"}
17
+ #permalink-manager .woocommerce-logo:before{content:"\e03d"}
18
+
19
  #permalink-manager .subsubsub{display:block;width:100%;overflow:hidden;margin-bottom:8px}
20
  #permalink-manager .subsubsub li:before{content:" | "}
21
  #permalink-manager .subsubsub li:first-child:before{content:"";color:#aaa}
22
+ #permalink-manager .subsubsub li .dashicons,#permalink-manager .subsubsub li .woocommerce-logo{font-size:100%;line-height:200%;height:auto;width:auto}
23
  #permalink-manager .tablenav{margin:15px 0;height:auto}
24
  #permalink-manager .tablenav.top{margin-top:0}
25
  #permalink-manager .tablenav .actions{padding:0;overflow:visible}
26
+ #permalink-manager .column-post_type,#permalink-manager .column-post_status,#permalink-manager .column-count,#permalink-manager .column-post_lang{width:13%}
27
+ #permalink-manager .column-count,#permalink-manager th#count{text-align:right}
28
+ #permalink-manager th#count a{display:inline-block}
29
  #permalink-manager .post_name input{max-width:100%}
30
+ #permalink-manager .post_permalink a,.post_permalink .dashicons{font-size:13px;color:#aaa;line-height:1.5em;height:auto;width:auto}
31
  #permalink-manager .post_permalink{margin-top:5px;display:block}
32
 
33
+ #permalink-manager .info{box-shadow:0 1px 1px 0 rgba(0,0,0,.1);display:block;overflow:hidden;clear:both;font-weight:bold;border-left:4px solid #dc3232;}
34
+ #permalink-manager .alert,#permalink-manager .info{line-height:19px;padding:11px 15px;margin:15px 0}
35
+ #permalink-manager .alert p,#permalink-manager .info p{margin-top:0;line-height:200%}
36
  #permalink-manager .alert ul,#permalink-manager .alert ol{margin-top:0;margin-bottom:0}
37
+ #permalink-manager .alert p:last-of-type,#permalink-manager .alert li:last-of-type,#permalink-manager .info p:last-of-type{margin-bottom:0}
38
  #permalink-manager .warning{background:#dc3232}
39
  #permalink-manager .warning,#permalink-manager .warning a{color:#fff}
40
  #permalink-manager .info{background:#f9f9f9}
46
  #permalink-manager .section-notes ol{margin-top:0;margin-bottom:0}
47
  #permalink-manager .section-notes ol li:last-of-type{margin-bottom:0}
48
  #permalink-manager .short-pre,#permalink-manager .short-textarea{height:150px;overflow:auto;max-width:100%;display:block}
49
+ #permalink-manager .structure-tags-list{margin-top:15px}
50
 
51
  #permalink-manager .checkbox_actions{padding-top:10px;border-top:1px solid #ddd}
52
  #permalink-manager .extra-links{margin-top:5px;font-size:12px}
53
+ #permalink-manager .extra-links a{color:#666;display:inline-block;text-decoration:none}
54
+ #permalink-manager .extra-links a:before{content:" | "}
55
+ #permalink-manager .extra-links a:first-child:before{content:""}
56
  #permalink-manager .checkboxes{margin-left:-15px;margin-right:15px;overflow:hidden;display:block}
57
  #permalink-manager .checkboxes > label{display:inline-block;width:33%;float:left;padding:0 15px;box-sizing:border-box;padding-bottom:5px}
58
+ #permalink-manager .checkboxes > label:nth-of-type(3n+1){clear:both}
59
  #permalink-manager .field-description{font-size:12px}
60
  #permalink-manager .appended-row td{padding-left:0;padding-right:0}
61
 
72
  * Breakpoints
73
  */
74
  @media only screen and (max-width : 782px) {
75
+ #permalink-manager .columns-container .column-1_2,#permalink-manager .columns-container .column-1_3,#permalink-manager .columns-container .column-2_3{width:100%}
76
  }
permalink-manager.php CHANGED
@@ -1,17 +1,17 @@
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;
@@ -20,11 +20,11 @@ if ( ! defined( 'WPINC' ) ) {
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
 
@@ -32,52 +32,58 @@ class Permalink_Manager_Class {
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 );
@@ -89,25 +95,28 @@ class Permalink_Manager_Class {
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;
@@ -117,116 +126,152 @@ class Permalink_Manager_Class {
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>";
@@ -242,7 +287,7 @@ class Permalink_Manager_Class {
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
  }
@@ -253,7 +298,7 @@ class Permalink_Manager_Class {
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
 
@@ -264,11 +309,27 @@ class Permalink_Manager_Class {
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
  }
1
  <?php
2
 
3
  /**
4
+ * Plugin Name: Permalink Manager
5
+ * Plugin URI: http://maciejbis.net/
6
+ * Description: Most advanced Permalink utility for Wordpress. It allows to bulk edit the permalinks & permastructures and regenerate/reset all the URIs in your Wordpress instance.
7
+ * Version: 1.0.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
  // If this file is called directly, abort.
16
  if ( ! defined( 'WPINC' ) ) {
17
  die;
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', '1.0.0' );
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://permalinkmanager.pro' );
28
 
29
  class Permalink_Manager_Class {
30
 
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->register_init_hooks();
40
  }
41
 
42
  /**
43
+ * Include back-end classess and set their instances
44
+ */
45
  function include_subclassess() {
 
 
 
 
 
46
  // WP_List_Table needed for post types & taxnomies editors
47
  if( ! class_exists( 'WP_List_Table' ) ) {
48
  require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
49
  }
50
 
51
+ $classes = array(
52
+ 'core' => array(
53
+ 'helper-functions' => 'Permalink_Manager_Helper_Functions',
54
+ 'uri-functions-post' => 'Permalink_Manager_URI_Functions_Post',
55
+ 'uri-functions-tax' => 'Permalink_Manager_URI_Functions_Tax',
56
+ 'admin-functions' => 'Permalink_Manager_Admin_Functions',
57
+ 'actions' => 'Permalink_Manager_Actions',
58
+ 'pro-hooks' => 'Permalink_Manager_Pro_Hooks'
59
+ ),
60
+ 'views' => array(
61
+ 'uri-editor' => 'Permalink_Manager_Uri_Editor',
62
+ 'tools' => 'Permalink_Manager_Tools',
63
+ 'permastructs' => 'Permalink_Manager_Permastructs',
64
+ 'settings' => 'Permalink_Manager_Settings',
65
+ 'advanced' => 'Permalink_Manager_Advanced',
66
+ 'uri-editor-tax' => false,
67
+ 'uri-editor-post' => false
68
+ )
69
+ );
70
+
71
+ // Load classes and set-up their instances
72
+ foreach($classes as $class_type => $classes_array) {
73
+ foreach($classes_array as $class => $class_name) {
74
+ $filename = PERMALINK_MANAGER_DIR . "/includes/{$class_type}/permalink-manager-{$class}.php";
75
+
76
+ if(file_exists($filename)) {
77
+ require_once $filename;
78
+ if($class_name) { $this->functions[$class] = new $class_name(); }
79
+ }
80
+ }
81
  }
82
  }
83
 
84
  /**
85
+ * Register general hooks
86
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  public function register_init_hooks() {
88
  // Localize plugin
89
  add_action( 'plugins_loaded', array($this, 'localize_me'), 1 );
95
  add_action( 'wp', array($this, 'disable_canonical_redirect'), 0, 1 );
96
  add_action( 'template_redirect', array($this, 'redirect_to_new_uri'), 999);
97
  add_filter( 'request', array($this, 'detect_post'), 0, 1 );
98
+
99
+ // Legacy support
100
+ add_action( 'init', array($this, 'legacy_support'), 2 );
101
  }
102
 
103
  /**
104
+ * Localize this plugin
105
+ */
106
  function localize_me() {
107
  load_plugin_textdomain( 'permalink-manager', false, PERMALINK_MANAGER_DIR );
108
  }
109
 
110
  /**
111
+ * Get options values & set global
112
+ */
113
  public function get_options_and_globals() {
114
  // 1. Globals with data stored in DB
115
  global $permalink_manager_options, $permalink_manager_uris, $permalink_manager_permastructs;
116
 
117
+ $this->permalink_manager_options = $permalink_manager_options = apply_filters('permalink-manager-options', get_option('permalink-manager', array()));
118
+ $this->permalink_manager_uris = $permalink_manager_uris = apply_filters('permalink-manager-uris', get_option('permalink-manager-uris', array()));
119
+ $this->permalink_manager_permastructs = $permalink_manager_permastructs = apply_filters('permalink-manager-permastructs', get_option('permalink-manager-permastructs', array()));
120
 
121
  // 2. Globals used to display additional content (eg. alerts)
122
  global $permalink_manager_before_sections_html, $permalink_manager_after_sections_html;
126
  }
127
 
128
  /**
129
+ * Used to optimize SQL queries amount instead of rewrite rules - the essential part of this plugin
130
+ */
131
  function detect_post($query) {
132
+ global $wpdb, $permalink_manager_uris, $sitepress_settings;
133
+
134
+ // Check if any custom URI is used
135
+ if(!(is_array($permalink_manager_uris))) return $query;
136
 
137
  // Used in debug mode
138
  $old_query = $query;
139
 
140
+ /**
141
+ * 1. Prepare URL and check if it is correct
142
+ */
143
+ $protocol = stripos($_SERVER['SERVER_PROTOCOL'], 'https') === true ? 'https://' : 'http://';
144
+ $request_url = "{$protocol}{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
145
+ $home_url = trim(rtrim(get_bloginfo('wpurl'), '/'));
146
+ // Adjust prefix (it should be the same in both request & home_url)
147
+ $home_url = ($protocol == 'https://') ? str_replace("http://", "https://", $home_url) : str_replace("https://", "http://", $home_url);
148
+
149
+ if (filter_var($request_url, FILTER_VALIDATE_URL)) {
150
+ /**
151
+ * 2. Process URL
152
+ */
153
+ // Remove .html suffix and domain name from URL and query (URLs ended with .html will work as aliases)
154
+ $request_url = trim(str_replace($home_url, "", $request_url), "/");
155
+
156
+ // Split the current URL into subparts (check if WPML is active)
157
+ if(isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 1) {
158
+ preg_match("/^(?:(\w{2})\/)?(.+)\/?(?:(page|feed|embed|attachment|track)\/([\d+])?)?$/i", $request_url, $url_parts);
159
+ $lang = (!empty($url_parts[1])) ? $url_parts[1] : "";
160
+ $uri = (!empty($url_parts[2])) ? $url_parts[2] : "";
161
+ $endpoint = (!empty($url_parts[3])) ? $url_parts[3] : "";
162
+ $endpoint_value = (!empty($url_parts[4])) ? $url_parts[4] : "";
163
+ } else {
164
+ preg_match("/^(.+)\/?(?:(page|feed|embed|attachment|track)\/([\d+])?)?$/i", $request_url, $url_parts);
165
+ $lang = false;
166
+ $uri = (!empty($url_parts[1])) ? $url_parts[1] : "";
167
+ $endpoint = (!empty($url_parts[2])) ? $url_parts[2] : "";
168
+ $endpoint_value = (!empty($url_parts[3])) ? $url_parts[3] : "";
169
  }
170
 
171
+ // Ignore URLs with no URI grabbed
 
 
172
  if(empty($uri)) return $query;
173
 
174
+ // Remove querystrings from URI
175
+ $uri = trim(strtok($uri, '?'), "/");
176
+
177
+ /**
178
+ * 2A. Check if found URI matches any element from custom uris array
179
+ */
180
+ $item_id = array_search($uri, $permalink_manager_uris);
181
 
182
  // Check again in case someone added .html suffix to particular post (with .html suffix)
183
+ $item_id = (empty($item_id)) ? array_search("{$uri}.html", $permalink_manager_uris) : $item_id;
184
+
185
+ // Clear the original query before it is filtered
186
+ $query = ($item_id) ? array() : $query;
187
 
188
+ /**
189
+ * 2B. Custom URI assigned to taxonomy
190
+ */
191
+ if(strpos($item_id, 'tax-') !== false) {
192
+ // Remove the "tax-" prefix
193
+ $item_id = preg_replace("/[^0-9]/", "", $item_id);
194
 
195
+ // Get the variables to filter wp_query and double-check if tax exists
196
+ $term = get_term($item_id);
197
+ if(empty($term->taxonomy)) { return $query; }
 
198
 
199
+ // Get some term data
200
+ $query_parameter = ($term->taxonomy == 'category') ? 'category_name' : $term->taxonomy;
201
+ $term_ancestors = get_ancestors($item_id, $term->taxonomy);
202
+ $final_uri = $term->slug;
 
 
203
 
204
+ // Fix for hierarchical CPT & pages
205
+ if(empty($term_ancestors)) {
206
+ foreach ($term_ancestors as $parent) {
207
+ $parent = get_term($parent, $term->taxonomy);
208
+ if(!empty($parent->slug)) {
209
+ $final_uri = $parent->slug . '/' . $final_uri;
210
+ }
211
+ }
212
  }
213
 
214
+ // Alter query parameters
215
+ $query[$query_parameter] = $final_uri;
216
+ }
217
+ /**
218
+ * 2C. Custom URI assigned to post/page/cpt item
219
+ */
220
+ else if(isset($item_id) && is_numeric($item_id)) {
221
+ // Fix for revisions
222
+ $is_revision = wp_is_post_revision($item_id);
223
+ $item_id = ($is_revision) ? $is_revision : $item_id;
224
+
225
+ // Fix for WPML languages mismatch
226
+ $post_lang_details = apply_filters('wpml_post_language_details', NULL, $item_id);
227
+ $language_code = (!empty($post_lang_details['language_code'])) ? $post_lang_details['language_code'] : '';
228
+ if($lang && $lang != $language_code) {
229
+ $item_id = apply_filters('wpml_object_id', $item_id);
230
+ }
231
 
232
+ $post_to_load = get_post($item_id);
233
+ $final_uri = $post_to_load->post_name;
234
  $post_type = $post_to_load->post_type;
 
 
235
 
236
  // Fix for hierarchical CPT & pages
237
+ if(!(empty($post_to_load->ancestors))) {
238
+ foreach ($post_to_load->ancestors as $parent) {
239
  $parent = get_post( $parent );
240
+ if($parent && $parent->post_name) {
241
+ $final_uri = $parent->post_name . '/' . $final_uri;
242
  }
243
  }
244
  }
245
 
 
 
 
 
 
 
 
246
  // Alter query parameters
247
  if($post_to_load->post_type == 'page') {
248
+ $query['pagename'] = $final_uri;
 
249
  } else if($post_to_load->post_type == 'post') {
250
+ $query['name'] = $final_uri;
251
  } else {
252
+ $query['name'] = $final_uri;
253
  $query['post_type'] = $post_type;
254
+ $query[$post_type] = $final_uri;
255
  }
256
 
257
  // Make the redirects more clever - see redirect_to_new_uri() method
258
  $query['do_not_redirect'] = 1;
259
+ }
260
 
261
+ /**
262
+ * 2C. Endpoints
263
+ */
264
+ if(!(empty($endpoint_value))) {
265
+ $endpoint = str_replace(array('page', 'trackback'), array('paged', 'tb'), $endpoint);
266
+ $query[$endpoint] = $endpoint_value;
267
  }
268
+
269
  }
270
 
271
  // Debug mode
272
  if(isset($_REQUEST['debug_url'])) {
273
  $debug_info['old_query_vars'] = $old_query;
274
  $debug_info['new_query_vars'] = $query;
 
 
275
 
276
  $debug_txt = json_encode($debug_info);
277
  $debug_txt = "<textarea style=\"width:100%;height:300px\">{$debug_txt}</textarea>";
287
  // Affect only posts with custom URI and old URIs
288
  if(is_singular() && isset($permalink_manager_uris[$wp_query->queried_object_id]) && empty($wp_query->query['do_not_redirect'])) {
289
  $current_url = home_url(add_query_arg(array(),$wp->request));
290
+ $native_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri($permalink_manager_uris[$wp_query->queried_object_id], true);
291
 
292
  $active_permalink = str_replace($native_uri, $permalink_manager_uris[$wp_query->queried_object_id], $current_url);
293
  }
298
  // Ignore default URIs (or do nothing if redirects are disabled)
299
  if(!empty($active_permalink) && !empty($redirect_mode)) {
300
  wp_redirect($active_permalink, $redirect_mode);
301
+ exit();
302
  }
303
  }
304
 
309
  }
310
  }
311
 
312
+ /**
313
+ * Temporary hook
314
+ */
315
+ function legacy_support() {
316
+ global $permalink_manager_permastructs, $permalink_manager_options;
317
+
318
+ if(isset($permalink_manager_options['base-editor'])) {
319
+ $new_options['post_types'] = $permalink_manager_options['base-editor'];
320
+ update_option('permalink-manager-permastructs', $new_options);
321
+ }
322
+ else if(empty($permalink_manager_permastructs['post_types']) && count($permalink_manager_permastructs) > 0) {
323
+ $new_options['post_types'] = $permalink_manager_permastructs;
324
+ update_option('permalink-manager-permastructs', $new_options);
325
+ }
326
+ }
327
+
328
  }
329
 
330
  /**
331
+ * Begins execution of the plugin.
332
+ */
333
  function run_permalink_manager() {
334
  $Permalink_Manager_Class = new Permalink_Manager_Class();
335
  }