Custom Permalinks - Version 1.6.0

Version Description

  • Aug 08, 2020 =

    • Bugs
    • Undefined index and undefined variable error
    • count(): Parameter must be an array or an object
    • Fix double slash from the permalink form
    • use 'view_item' label for previewing custom post types
    • Fix PHP 7.4 issues
    • Fix Yoast Canonical double slash issue
    • Replacing category_link with term_link
    • Bug with WPML and Use directory for default language
    • Fix Static Homepage redirect issue
    • Enhancements
    • Improved Gutenberg Support
    • Added compatibility for WPML language switcher
    • Add filter to exclude Custom Permalinks for certain posts (based on Post IDs, template, etc)
    • Optimized Code
Download this release

Release Info

Developer sasiddiqui
Plugin Icon Custom Permalinks
Version 1.6.0
Comparing to
See all releases

Code changes from version 1.5.1 to 1.6.0

admin/class-custom-permalinks-about.php CHANGED
@@ -1,151 +1,266 @@
1
  <?php
2
  /**
3
- * @package CustomPermalinks\Admin
4
  */
5
 
6
- class Custom_Permalinks_About {
7
-
8
- /**
9
- * Class constructor.
10
- */
11
- public function __construct() {
12
- $this->more_plugins();
13
- }
14
-
15
- /**
16
- * Print HTML for Custom Permalinks ABout Page
17
- *
18
- * @access private
19
- * @since 1.2.11
20
- * @return void
21
- */
22
- private function more_plugins() {
23
- $plugin_url = plugins_url( '/admin', CUSTOM_PERMALINKS_FILE );
24
- $img_src = $plugin_url . '/images';
25
- wp_enqueue_style( 'style', $plugin_url . '/css/about-plugins.min.css' );
26
- $plugin_name = __( 'Custom Permalinks', 'custom-permalinks' );
27
- $button_text = __( 'Check it out', 'custom-permalinks' );
28
- $five_star = '<span class="star">
29
- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 53.867 53.867" width="15" height="15">
30
- <polygon points="26.934,1.318 35.256,18.182 53.867,20.887 40.4,34.013 43.579,52.549 26.934,43.798
31
- 10.288,52.549 13.467,34.013 0,20.887 18.611,18.182 "/>
32
- </svg>
33
- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 53.867 53.867" width="15" height="15">
34
- <polygon points="26.934,1.318 35.256,18.182 53.867,20.887 40.4,34.013 43.579,52.549 26.934,43.798
35
- 10.288,52.549 13.467,34.013 0,20.887 18.611,18.182 "/>
36
- </svg>
37
- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 53.867 53.867" width="15" height="15">
38
- <polygon points="26.934,1.318 35.256,18.182 53.867,20.887 40.4,34.013 43.579,52.549 26.934,43.798
39
- 10.288,52.549 13.467,34.013 0,20.887 18.611,18.182 "/>
40
- </svg>
41
- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 53.867 53.867" width="15" height="15">
42
- <polygon points="26.934,1.318 35.256,18.182 53.867,20.887 40.4,34.013 43.579,52.549 26.934,43.798
43
- 10.288,52.549 13.467,34.013 0,20.887 18.611,18.182 "/>
44
- </svg>
45
- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 53.867 53.867" width="15" height="15">
46
- <polygon points="26.934,1.318 35.256,18.182 53.867,20.887 40.4,34.013 43.579,52.549 26.934,43.798
47
- 10.288,52.549 13.467,34.013 0,20.887 18.611,18.182 "/>
48
- </svg>
49
- </span>';
50
- ?>
51
-
52
- <div class="wrap">
53
- <div class="float">
54
- <h1><?php echo $plugin_name . ' v' . CUSTOM_PERMALINKS_PLUGIN_VERSION; ?></h1>
55
- <div class="tagline">
56
- <p><?php _e('Thank you for choosing Custom Permalinks! We hope that your experience with our plugin for updating permalinks is quick and easy. We are trying to make it more feasible for you and provide capabilities in it.', 'custom-permalinks' ); ?></p>
57
- <p><?php printf( __( 'To support future development and help to make it even better just leaving us a <a href="%s" title="Custom Permalinks Rating" target="_blank">%s</a> rating with a nice message to me :)', 'custom-permalinks' ), 'https://wordpress.org/support/plugin/custom-permalinks/reviews/?rate=5#new-post', $five_star ); ?></p>
58
- </div>
59
- </div>
60
-
61
- <div class="float">
62
- <object type="image/svg+xml" data="<?php echo $img_src;?>/custom-permalinks.svg" width="128" height="128"></object>
63
- </div>
64
-
65
- <div class="product">
66
- <h2><?php _e( 'More from Sami Ahmed Siddiqui', 'custom-permalinks' ); ?></h2>
67
- <span><?php _e('Our List of Plugins provides the services which help you to manage your site URLs(Permalinks), Prevent your site from XSS Attacks, Brute force attacks, increase your site visitors by adding Structured JSON Markup and so on.', 'custom-permalinks' ); ?></span>
68
- <div class="box recommended">
69
- <div class="img">
70
- <img src= "<?php echo $img_src; ?>/prevent-xss-vulnerability.png" style="transform:scale(1.5)" />
71
- </div>
72
 
73
- <h3><?php _e( 'Prevent XSS Vulnerability', 'custom-permalinks' ); ?></h3>
74
- <p><?php _e( 'Secure your site from the <strong>XSS Attacks</strong> so, your users won\'t lose any kind of information or not redirected to any other site by visiting your site with the <strong>malicious code</strong> in the URL or so. In this way, users can open their site URLs without any hesitation.', 'custom-permalinks' ); ?></p>
75
- <a href="https://wordpress.org/plugins/prevent-xss-vulnerability/" class="checkout-button" target="_blank"><?php echo $button_text; ?></a>
76
- </div>
 
 
 
77
 
78
- <div class="box">
79
- <div class="img">
80
- <img src= "<?php echo $img_src; ?>/permalinks-customizer.svg" />
81
- </div>
 
 
 
 
 
 
 
82
 
83
- <h3><?php _e( 'Permalinks Customizer', 'custom-permalinks' ); ?></h3>
84
- <p><?php _e( 'Allows you to either define different Permalink Structure or define same Permalink Structure for default and Custom PostTypes, Taxonomies. The plugin automatically creates the user-friendly URLs as per your defined structure that can be edited from the single post/page.', 'custom-permalinks' ); ?></p>
85
- <a href="https://wordpress.org/plugins/permalinks-customizer/" class="checkout-button" target="_blank"><?php echo $button_text; ?></a>
86
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
- <div class="box recommended">
89
- <div class="img">
90
- <img src= "<?php echo $img_src; ?>/http-auth.svg" />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  </div>
92
 
93
- <h3><?php _e( 'Http Auth', 'schema-for-article' ); ?></h3>
94
- <p><?php _e( 'Allows you apply <strong>HTTP Auth</strong> on your site. You can apply Http Authentication all over the site or only the admin pages. It helps to stop crawling on your site while on development or persist the <strong>Brute Attacks</strong> by locking the Admin Pages.', 'schema-for-article' ); ?></p>
95
- <a href="https://wordpress.org/plugins/http-auth/" class="checkout-button" target="_blank"><?php echo $button_text; ?></a>
96
- </div>
97
-
98
- <div class="box">
99
- <div class="img">
100
- <img src= "<?php echo $img_src; ?>/schema-for-article.svg" />
101
  </div>
102
 
103
- <h3><?php _e( 'SCHEMA for Article', 'schema-for-article' ); ?></h3>
104
- <p><?php _e( 'Simply the easiest solution to add valid schema.org as a JSON script in the head of blog posts or articles. You can choose the schema either to show with the type of Article or NewsArticle from the settings page.', 'schema-for-article' ); ?></p>
105
- <a href="https://wordpress.org/plugins/schema-for-article/" class="checkout-button" target="_blank"><?php echo $button_text; ?></a>
106
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
- <div class="box">
109
- <div class="img">
110
- <img src= "<?php echo $img_src; ?>/make-paths-relative.svg" />
111
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
- <h3><?php _e( 'Make Paths Relative', 'custom-permalinks' ); ?></h3>
114
- <p><?php _e( 'Convert the paths(URLs) to relative instead of absolute. You can make <strong>Post</strong>, <strong>Category</strong>, <strong>Archive</strong>, <strong>Image</strong> URLs and <strong>Script</strong> and <strong>Style</strong> src as per your requirement. You can choose which you want to be relative from the settings Page.', 'custom-permalinks' ); ?></p>
115
- <a href="https://wordpress.org/plugins/make-paths-relative/" class="checkout-button" target="_blank"><?php echo $button_text; ?></a>
116
- </div>
117
 
118
- <div class="box">
119
- <div class="img">
120
- <img src= "<?php echo $img_src; ?>/json-structuring-markup.svg" />
121
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
- <h3><?php _e( 'JSON Structuring Markup', 'custom-permalinks' ); ?></h3>
124
- <p><?php _e( 'Simply the easiest solution to add valid schema.org as a JSON script in the head of posts and pages. It provides you multiple <strong>SCHEMA</strong> types like Article, News Article, Organization and Website Schema.', 'custom-permalinks' ); ?></p>
125
- <a href="https://wordpress.org/plugins/json-structuring-markup/" class="checkout-button" target="_blank"><?php echo $button_text; ?></a>
126
- </div>
127
 
128
- <div class="box">
129
- <div class="img">
130
- <img src= "<?php echo $img_src; ?>/remove-links-and-scripts.svg" />
131
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
132
 
133
- <h3><?php _e( 'Remove Links and Scripts', 'custom-permalinks' ); ?></h3>
134
- <p><?php _e( 'It removes some meta data from the wordpress header so, your header keeps clean of useless information like <strong>shortlink</strong>, <strong>rsd_link</strong>, <strong>wlwmanifest_link</strong>, <strong>emoji_scripts</strong>, <strong>wp_embed</strong>, <strong>wp_json</strong>, <strong>emoji_styles</strong>, <strong>generator</strong> and so on.', 'custom-permalinks' ); ?></p>
135
- <a href="https://wordpress.org/plugins/remove-links-and-scripts/" class="checkout-button" target="_blank"><?php echo $button_text; ?></a>
136
- </div>
137
 
138
- <div class="box">
139
- <div class="img">
140
- <img src= "<?php echo $img_src; ?>/media-post-permalink.png" style="transform:scale(1.5)" />
141
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
- <h3><?php _e( 'Media Post Permalink', 'custom-permalinks' ); ?></h3>
144
- <p><?php _e( 'On uploading any image, let\'s say services.png, WordPress creates the <strong>attachment post</strong> with the permalink of <strong>/services/</strong> and doesn\'t allow you to use that permalink to point your page. In this case, we come up with this great solution.', 'custom-permalinks' ); ?></p>
145
- <a href="https://wordpress.org/plugins/media-post-permalink/" class="checkout-button" target="_blank"><?php echo $button_text; ?></a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  </div>
147
- </div>
148
- </div>
149
- <?php
150
- }
151
  }
1
  <?php
2
  /**
3
+ * @package CustomPermalinks
4
  */
5
 
6
+ class Custom_Permalinks_About
7
+ {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
+ /**
10
+ * Class constructor.
11
+ */
12
+ public function __construct()
13
+ {
14
+ $this->more_plugins();
15
+ }
16
 
17
+ /**
18
+ * Print HTML for Custom Permalinks About Page.
19
+ *
20
+ * @since 1.2.11
21
+ * @access private
22
+ */
23
+ private function more_plugins()
24
+ {
25
+ $plugin_url = plugins_url( '/admin', CUSTOM_PERMALINKS_FILE );
26
+ $img_src = $plugin_url . '/images';
27
+ wp_enqueue_style( 'style', $plugin_url . '/css/about-plugins.min.css' );
28
 
29
+ $fivestar = '<span class="star">
30
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 53.867 53.867" width="15" height="15">
31
+ <polygon points="26.934,1.318 35.256,18.182 53.867,20.887 40.4,34.013 43.579,52.549 26.934,43.798
32
+ 10.288,52.549 13.467,34.013 0,20.887 18.611,18.182 "/>
33
+ </svg>
34
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 53.867 53.867" width="15" height="15">
35
+ <polygon points="26.934,1.318 35.256,18.182 53.867,20.887 40.4,34.013 43.579,52.549 26.934,43.798
36
+ 10.288,52.549 13.467,34.013 0,20.887 18.611,18.182 "/>
37
+ </svg>
38
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 53.867 53.867" width="15" height="15">
39
+ <polygon points="26.934,1.318 35.256,18.182 53.867,20.887 40.4,34.013 43.579,52.549 26.934,43.798
40
+ 10.288,52.549 13.467,34.013 0,20.887 18.611,18.182 "/>
41
+ </svg>
42
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 53.867 53.867" width="15" height="15">
43
+ <polygon points="26.934,1.318 35.256,18.182 53.867,20.887 40.4,34.013 43.579,52.549 26.934,43.798
44
+ 10.288,52.549 13.467,34.013 0,20.887 18.611,18.182 "/>
45
+ </svg>
46
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 53.867 53.867" width="15" height="15">
47
+ <polygon points="26.934,1.318 35.256,18.182 53.867,20.887 40.4,34.013 43.579,52.549 26.934,43.798
48
+ 10.288,52.549 13.467,34.013 0,20.887 18.611,18.182 "/>
49
+ </svg>
50
+ </span>';
51
+ ?>
52
 
53
+ <div class="wrap">
54
+ <div class="float">
55
+ <h1>
56
+ <?php
57
+ esc_html_e( 'Custom Permalinks v' . CUSTOM_PERMALINKS_PLUGIN_VERSION, 'custom-permalinks' );
58
+ ?>
59
+ </h1>
60
+ <div class="tagline">
61
+ <p>
62
+ <?php
63
+ esc_html_e(
64
+ 'Thank you for choosing Custom Permalinks! We hope that your experience with our plugin for updating permalinks is quick and easy. We are trying to make it more feasible for you and provide capabilities in it.',
65
+ 'custom-permalinks'
66
+ );
67
+ ?>
68
+ </p>
69
+ <p>
70
+ <?php
71
+ printf(
72
+ __(
73
+ 'To support future development and help to make it even better just leaving us a <a href="%s" title="Custom Permalinks Rating" target="_blank">%s</a> rating with a nice message to me :)',
74
+ 'custom-permalinks'
75
+ ),
76
+ 'https://wordpress.org/support/plugin/custom-permalinks/reviews/?rate=5#new-post',
77
+ $fivestar
78
+ );
79
+ ?>
80
+ </p>
81
+ </div>
82
  </div>
83
 
84
+ <div class="float">
85
+ <object type="image/svg+xml" data="<?php echo esc_url( $img_src . '/custom-permalinks.svg' );?>" width="128" height="128"></object>
 
 
 
 
 
 
86
  </div>
87
 
88
+ <div class="product">
89
+ <h2>
90
+ <?php
91
+ esc_html_e( 'More from Sami Ahmed Siddiqui', 'custom-permalinks' );
92
+ ?>
93
+ </h2>
94
+ <span>
95
+ <?php
96
+ esc_html_e(
97
+ 'Our List of Plugins provides the services which help you to prevent your site from XSS Attacks, Brute force attack, change absolute paths to relative, increase your site visitors by adding Structured JSON Markup and so on.',
98
+ 'custom-permalinks'
99
+ );
100
+ ?>
101
+ </span>
102
+ <div class="box recommended">
103
+ <div class="img">
104
+ <img src="<?php echo esc_url( $img_src . '/prevent-xss-vulnerability.png' ); ?>" style="transform:scale(1.5)" />
105
+ </div>
106
 
107
+ <h3>
108
+ <?php
109
+ esc_html_e( 'Prevent XSS Vulnerability', 'custom-permalinks' );
110
+ ?>
111
+ </h3>
112
+ <p>
113
+ <?php
114
+ esc_html_e(
115
+ 'Secure your site from the XSS Attacks so, your users won\'t lose any kind of information or not redirected to any other site by visiting your site with the malicious code in the URL or so. In this way, users can open their site URLs without any hesitation.',
116
+ 'custom-permalinks'
117
+ );
118
+ ?>
119
+ </p>
120
+ <a href="https://wordpress.org/plugins/prevent-xss-vulnerability/" class="checkout-button" target="_blank">
121
+ <?php esc_html_e( 'Check it out', 'custom-permalinks' ); ?>
122
+ </a>
123
+ </div>
124
 
125
+ <div class="box recommended">
126
+ <div class="img">
127
+ <img src="<?php echo esc_url( $img_src . '/http-auth.svg' ); ?>" />
128
+ </div>
129
 
130
+ <h3>
131
+ <?php
132
+ esc_html_e( 'HTTP Auth', 'custom-permalinks' );
133
+ ?>
134
+ </h3>
135
+ <p>
136
+ <?php
137
+ esc_html_e(
138
+ 'Allows you apply HTTP Auth on your site. You can apply Http Authentication all over the site or only the admin pages. It helps to stop crawling on your site while on development or persist the Brute Attacks by locking the Admin Pages.',
139
+ 'custom-permalinks'
140
+ );
141
+ ?>
142
+ </p>
143
+ <a href="https://wordpress.org/plugins/http-auth/" class="checkout-button" target="_blank">
144
+ <?php esc_html_e( 'Check it out', 'custom-permalinks' ); ?>
145
+ </a>
146
+ </div>
147
 
148
+ <div class="box">
149
+ <div class="img">
150
+ <img src="<?php echo esc_url( $img_src . '/make-paths-relative.svg' ); ?>" />
151
+ </div>
152
 
153
+ <h3>
154
+ <?php
155
+ esc_html_e( 'Make Paths Relative', 'custom-permalinks' );
156
+ ?>
157
+ </h3>
158
+ <p>
159
+ <?php
160
+ esc_html_e(
161
+ 'Convert the paths(URLs) to relative instead of absolute. You can make Post, Category, Archive, Image URLs and Script and Style src as per your requirement. You can choose which you want to be relative from the settings Page.',
162
+ 'custom-permalinks'
163
+ );
164
+ ?>
165
+ </p>
166
+ <a href="https://wordpress.org/plugins/make-paths-relative/" class="checkout-button" target="_blank">
167
+ <?php esc_html_e( 'Check it out', 'custom-permalinks' ); ?>
168
+ </a>
169
+ </div>
170
 
171
+ <div class="box">
172
+ <div class="img">
173
+ <img src="<?php echo esc_url( $img_src . '/schema-for-article.svg' ); ?>" />
174
+ </div>
175
 
176
+ <h3>
177
+ <?php
178
+ esc_html_e( 'SCHEMA for Article', 'custom-permalinks' );
179
+ ?>
180
+ </h3>
181
+ <p>
182
+ <?php
183
+ esc_html_e(
184
+ 'Simply the easiest solution to add valid schema.org as a JSON script in the head of blog posts or articles. You can choose the schema either to show with the type of Article or NewsArticle from the settings page.',
185
+ 'custom-permalinks'
186
+ );
187
+ ?>
188
+ </p>
189
+ <a href="https://wordpress.org/plugins/schema-for-article/" class="checkout-button" target="_blank">
190
+ <?php esc_html_e( 'Check it out', 'custom-permalinks' ); ?>
191
+ </a>
192
+ </div>
193
+
194
+ <div class="box">
195
+ <div class="img">
196
+ <img src="<?php echo esc_url( $img_src . '/remove-links-and-scripts.svg' ); ?>" />
197
+ </div>
198
 
199
+ <h3>
200
+ <?php
201
+ esc_html_e( 'Remove Links and Scripts', 'custom-permalinks' );
202
+ ?>
203
+ </h3>
204
+ <p>
205
+ <?php
206
+ esc_html_e(
207
+ 'It removes some meta data from the wordpress header so, your header keeps clean of useless information like shortlink, rsd_link, wlwmanifest_link, emoji_scripts, wp_embed, wp_json, emoji_styles, generator and so on.',
208
+ 'custom-permalinks'
209
+ );
210
+ ?>
211
+ </p>
212
+ <a href="https://wordpress.org/plugins/remove-links-and-scripts/" class="checkout-button" target="_blank">
213
+ <?php esc_html_e( 'Check it out', 'custom-permalinks' ); ?>
214
+ </a>
215
+ </div>
216
+
217
+ <div class="box">
218
+ <div class="img">
219
+ <img src="<?php echo esc_url( $img_src . '/media-post-permalink.png' ); ?>" style="transform:scale(1.5)" />
220
+ </div>
221
+
222
+ <h3>
223
+ <?php
224
+ esc_html_e( 'Media Post Permalink', 'custom-permalinks' );
225
+ ?>
226
+ </h3>
227
+ <p>
228
+ <?php
229
+ esc_html_e(
230
+ 'On uploading any image, let\'s say services.png, WordPress creates the attachment post with the permalink of /services/ and doesn\'t allow you to use that permalink to point your page. In this case, we come up with this great solution.',
231
+ 'custom-permalinks'
232
+ );
233
+ ?>
234
+ </p>
235
+ <a href="https://wordpress.org/plugins/media-post-permalink/" class="checkout-button" target="_blank">
236
+ <?php esc_html_e( 'Check it out', 'custom-permalinks' ); ?>
237
+ </a>
238
+ </div>
239
+
240
+ <div class="box">
241
+ <div class="img">
242
+ <img src="<?php echo esc_url( $img_src . '/json-structuring-markup.svg' ); ?>" />
243
+ </div>
244
+
245
+ <h3>
246
+ <?php
247
+ esc_html_e( 'JSON Structuring Markup', 'custom-permalinks' );
248
+ ?>
249
+ </h3>
250
+ <p>
251
+ <?php
252
+ esc_html_e(
253
+ 'Simply the easiest solution to add valid schema.org as a JSON script in the head of posts and pages. It provides you multiple SCHEMA types like Article, News Article, Organization and Website Schema.',
254
+ 'custom-permalinks'
255
+ );
256
+ ?>
257
+ </p>
258
+ <a href="https://wordpress.org/plugins/json-structuring-markup/" class="checkout-button" target="_blank">
259
+ <?php esc_html_e( 'Check it out', 'custom-permalinks' ); ?>
260
+ </a>
261
+ </div>
262
+ </div>
263
  </div>
264
+ <?php
265
+ }
 
 
266
  }
admin/class-custom-permalinks-admin.php CHANGED
@@ -1,585 +1,175 @@
1
  <?php
2
  /**
3
- * @package CustomPermalinks\Admin
4
  */
5
 
6
- class Custom_Permalinks_Admin {
7
-
8
- /**
9
- * Initializes WordPress hooks
10
- */
11
- function __construct() {
12
- add_action( 'admin_menu', array( $this, 'admin_menu' ) );
13
- add_filter( 'plugin_action_links_' . CUSTOM_PERMALINKS_BASENAME,
14
- array( $this, 'settings_link' )
15
- );
16
- add_action( 'admin_init', array( $this, 'cp_privacy_policy' ) );
17
- }
18
-
19
- /**
20
- * Added Pages in Menu for Settings
21
- *
22
- * @access public
23
- * @since 1.2
24
- * @return void
25
- */
26
- public function admin_menu() {
27
- add_menu_page( 'Custom Permalinks', 'Custom Permalinks', 'cp_view_post_permalinks',
28
- 'cp-post-permalinks', array( $this,'posttype_permalinks' ),
29
- 'dashicons-admin-links'
30
- );
31
- add_submenu_page( 'cp-post-permalinks', 'PostTypes Permalinks',
32
- 'PostTypes Permalinks', 'cp_view_post_permalinks', 'cp-post-permalinks',
33
- array( $this, 'posttype_permalinks' )
34
- );
35
- add_submenu_page( 'cp-post-permalinks', 'Category Permalinks',
36
- 'Category Permalinks', 'cp_view_category_permalinks', 'cp-category-permalinks',
37
- array( $this, 'category_permalinks' )
38
- );
39
- add_submenu_page( 'cp-post-permalinks', 'About Custom Permalinks',
40
- 'About CP', 'install_plugins', 'cp-about-plugins',
41
- array( $this, 'about_plugin' )
42
- );
43
- }
44
-
45
- /**
46
- * Shows all the Permalinks created by using this Plugin with Pager and
47
- * Search Functionality of Posts/Pages.
48
- *
49
- * @access public
50
- * @since 1.2
51
- * @return void
52
- */
53
- public function posttype_permalinks() {
54
- global $wpdb;
55
- $filter_options = '';
56
- $filter_permalink = '';
57
- $search_permalink = '';
58
- $html = '';
59
- $error = '';
60
-
61
- // Handle Bulk Operations
62
- if ( ( isset( $_POST['action'] ) && $_POST['action'] == 'delete' )
63
- || ( isset( $_POST['action2'] ) && $_POST['action2'] == 'delete' )
64
- && isset( $_POST['permalink'] ) && ! empty( $_POST['permalink'] ) ) {
65
- $post_ids = implode( ',', $_POST['permalink'] );
66
- if ( preg_match( '/^\d+(?:,\d+)*$/', $post_ids ) ) {
67
- $wpdb->query( "DELETE FROM $wpdb->postmeta WHERE post_id IN ($post_ids) AND meta_key = 'custom_permalink'" );
68
- } else {
69
- $error = '<div id="message" class="error">
70
- <p>' . __( 'There is some error to proceed your request. Please retry with your request or contact to the plugin author.', 'custom-permalinks' ) . '</p>
71
- </div>';
72
- }
73
- }
74
- $html .= '<div class="wrap">
75
- <h1 class="wp-heading-inline">' . __( 'PostTypes Permalinks', 'custom-permalinks' ) . '</h1>';
76
- $html .= $error;
77
-
78
- $search_value = '';
79
- if ( isset( $_GET['s'] ) && ! empty( $_GET['s'] ) ) {
80
- $filter_permalink = 'AND pm.meta_value LIKE "%' . $_GET['s'] . '%"';
81
- $search_permalink = '&s=' . $_GET['s'] . '';
82
- $search_value = ltrim( htmlspecialchars( $_GET['s'] ), '/' );
83
- $html .= '<span class="subtitle">Search results for "' . $search_value . '"</span>';
84
- }
85
- $page_limit = 'LIMIT 0, 20';
86
- if ( isset( $_GET['paged'] ) && is_numeric( $_GET['paged'] )
87
- && $_GET['paged'] > 1 ) {
88
- $pager = 20 * ( $_GET['paged'] - 1 );
89
- $page_limit = 'LIMIT ' . $pager . ', 20';
90
- }
91
- $sorting_by = 'ORDER By p.ID DESC';
92
- $order_by = 'asc';
93
- $order_by_class = 'desc';
94
- if ( isset( $_GET['orderby'] ) && $_GET['orderby'] == 'title' ) {
95
- $filter_options .= '<input type="hidden" name="orderby" value="title" />';
96
- if ( isset( $_GET['order'] ) && $_GET['order'] == 'desc' ) {
97
- $sorting_by = 'ORDER By p.post_title DESC';
98
- $order_by = 'asc';
99
- $order_by_class = 'desc';
100
- $filter_options .= '<input type="hidden" name="order" value="desc" />';
101
- } else {
102
- $sorting_by = 'ORDER By p.post_title';
103
- $order_by = 'desc';
104
- $order_by_class = 'asc';
105
- $filter_options .= '<input type="hidden" name="order" value="asc" />';
106
- }
107
  }
108
- $count_query = "SELECT COUNT(p.ID) AS total_permalinks FROM $wpdb->posts AS p LEFT JOIN $wpdb->postmeta AS pm ON (p.ID = pm.post_id) WHERE pm.meta_key = 'custom_permalink' AND pm.meta_value != '' " . $filter_permalink . "";
109
- $count_posts = $wpdb->get_row( $count_query );
110
-
111
- $html .= '<form action="' . $_SERVER["REQUEST_URI"] . '" method="get">';
112
- $html .= '<p class="search-box">';
113
- $html .= '<input type="hidden" name="page" value="cp-post-permalinks" />';
114
- $html .= $filter_options;
115
- $html .= '<label class="screen-reader-text" for="custom-permalink-search-input">Search Custom Permalink:</label>';
116
- $html .= '<input type="search" id="custom-permalink-search-input" name="s" value="' . $search_value . '">';
117
- $html .= '<input type="submit" id="search-submit" class="button" value="Search Permalink"></p>';
118
- $html .= '</form>';
119
- $html .= '<form action="' . $_SERVER["REQUEST_URI"] . '" method="post">';
120
- $html .= '<div class="tablenav top">';
121
- $html .= '<div class="alignleft actions bulkactions">
122
- <label for="bulk-action-selector-top" class="screen-reader-text">Select bulk action</label>
123
- <select name="action" id="bulk-action-selector-top">
124
- <option value="-1">' . __( "Bulk Actions", "custom-permalinks" ) . '</option>
125
- <option value="delete">' . __( "Delete Permalinks", "custom-permalinks" ) . '</option>
126
- </select>
127
- <input type="submit" id="doaction" class="button action" value="Apply">
128
- </div>';
129
-
130
- $posts = 0;
131
- $pagination_html = '';
132
- if ( isset( $count_posts->total_permalinks )
133
- && $count_posts->total_permalinks > 0 ) {
134
-
135
- $html .= '<h2 class="screen-reader-text">Custom Permalink navigation</h2>';
136
 
137
- $query = "SELECT p.ID, p.post_title, p.post_type, pm.meta_value FROM $wpdb->posts AS p LEFT JOIN $wpdb->postmeta AS pm ON (p.ID = pm.post_id) WHERE pm.meta_key = 'custom_permalink' AND pm.meta_value != '' " . $filter_permalink . " " . $sorting_by . " " . $page_limit . "";
138
- $posts = $wpdb->get_results( $query );
139
-
140
- $total_pages = ceil( $count_posts->total_permalinks / 20 );
141
- if ( isset( $_GET['paged'] ) && is_numeric( $_GET['paged'] )
142
- && $_GET['paged'] > 0 ) {
143
- $pagination_html = $this->cp_pager(
144
- $count_posts->total_permalinks, $_GET['paged'], $total_pages
 
 
 
145
  );
146
- if ( $_GET['paged'] > $total_pages ) {
147
- $redirect_uri = explode(
148
- '&paged=' . $_GET['paged'] . '', $_SERVER['REQUEST_URI']
149
- );
150
- header( 'Location: ' . $redirect_uri[0], 301 );
151
- exit();
152
- }
153
- } elseif ( ! isset( $_GET['paged'] ) ) {
154
- $pagination_html = $this->cp_pager(
155
- $count_posts->total_permalinks, 1, $total_pages
156
  );
157
- }
158
-
159
- $html .= $pagination_html;
160
  }
161
- $table_navigation = $this->tablenav_posts(
162
- $order_by_class, $order_by, $search_permalink
163
- );
164
 
165
- $html .= '</div>';
166
- $html .= '<table class="wp-list-table widefat fixed striped posts">
167
- <thead>' . $table_navigation . '</thead>
168
- <tbody>';
169
- if ( $posts != 0 && ! empty( $posts ) ) {
170
- foreach ( $posts as $post ) {
171
- $html .= '<tr valign="top">';
172
- $html .= '<th scope="row" class="check-column">
173
- <input type="checkbox" name="permalink[]" value="' . $post->ID . '" />
174
- </th>';
175
- $html .= '<td><strong>
176
- <a class="row-title" href="post.php?action=edit&post=' . $post->ID . '">' . $post->post_title . '</a>
177
- </strong></td>';
178
- $html .= '<td>' . ucwords( $post->post_type ) . '</td>';
179
- $html .= '<td>
180
- <a href="/' . $post->meta_value . '" target="_blank" title="' . __( "Visit " . $post->post_title, "custom-permalinks" ) . '">/' . urldecode( $post->meta_value ) . '</a>
181
- </td>';
182
- $html .= '</tr>';
183
- }
184
- } else {
185
- $html .= '<tr class="no-items">
186
- <td class="colspanchange" colspan="10">No permalinks found.</td>
187
- </tr>';
188
  }
189
- $html .= '</tbody>
190
- <tfoot>' . $table_navigation . '</tfoot>
191
- </table>';
192
-
193
- $html .= '<div class="tablenav bottom">
194
- <div class="alignleft actions bulkactions">
195
- <label for="bulk-action-selector-bottom" class="screen-reader-text">Select bulk action</label>
196
- <select name="action2" id="bulk-action-selector-bottom">
197
- <option value="-1">' . __( "Bulk Actions", "custom-permalinks" ) . '</option>
198
- <option value="delete">' . __( "Delete Permalinks", "custom-permalinks" ) . '</option>
199
- </select>
200
- <input type="submit" id="doaction2" class="button action" value="Apply">
201
- </div>
202
- ' . $pagination_html . '
203
- </div>';
204
- $html .= '</form></div>';
205
- echo $html;
206
-
207
- add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
208
- }
209
-
210
- /**
211
- * Return the Navigation row HTML same as Default Posts page for PostTypes
212
- *
213
- * @access private
214
- * @since 1.2
215
- * @return string
216
- */
217
- private function tablenav_posts( $order_by_class, $order_by, $search_permalink ) {
218
- $nav = '<tr>
219
- <td id="cb" class="manage-column column-cb check-column">
220
- <label class="screen-reader-text" for="cb-select-all-1">Select All</label>
221
- <input id="cb-select-all-1" type="checkbox">
222
- </td>
223
- <th scope="col" id="title" class="manage-column column-title column-primary sortable ' . $order_by_class . '">
224
- <a href="/wp-admin/admin.php?page=cp-post-permalinks&amp;orderby=title&amp;order=' . $order_by . $search_permalink . '"><span>' . __( "Title", "custom-permalinks" ) . '</span><span class="sorting-indicator"></span></a>
225
- </th>
226
- <th scope="col">' . __( "Type", "custom-permalinks" ) . '</th>
227
- <th scope="col">' . __( "Permalink", "custom-permalinks" ) . '</th>
228
- </tr>';
229
- return $nav;
230
- }
231
-
232
- /**
233
- * Shows all the Permalinks created by using this Plugin with Pager and
234
- * Search Functionality of Category/Tags
235
- *
236
- * @access public
237
- * @since 1.2
238
- * @return void
239
- */
240
- public function category_permalinks() {
241
-
242
- $search_permalink = '';
243
- $html = '';
244
 
245
- // Handle Bulk Operations
246
- if ( ( isset( $_POST['action'] ) && $_POST['action'] == 'delete' )
247
- || ( isset( $_POST['action2'] ) && $_POST['action2'] == 'delete' )
248
- && isset( $_POST['permalink'] ) && ! empty( $_POST['permalink'] ) ) {
249
- $remove_perm = $_POST['permalink'];
250
- $data = get_option( 'custom_permalink_table' );
251
- if ( isset( $data ) && is_array( $data ) ) {
252
- $i = 0;
253
- foreach ( $data as $link => $info ) {
254
- if ( in_array( $info['id'], $remove_perm ) ) {
255
- unset( $data[$link] );
256
- unset( $remove_perm[$i] );
257
- if ( ! is_array( $remove_perm ) || empty( $remove_perm ) )
258
- break;
259
- }
260
- $i++;
261
- }
262
- }
263
- update_option( 'custom_permalink_table', $data );
264
  }
265
- $html .= '<div class="wrap">
266
- <h1 class="wp-heading-inline">' . __( 'Category/Tags Permalinks', 'custom-permalinks' ) . '</h1>';
267
 
268
- $search_value = '';
269
- if ( isset( $_GET['s'] ) && ! empty( $_GET['s'] ) ) {
270
- $search_permalink = '&s=' . $_GET['s'] . '';
271
- $search_value = ltrim( htmlspecialchars( $_GET['s'] ), '/' );
272
- $html .= '<span class="subtitle">Search results for "' . $search_value . '"</span>';
273
- }
274
- $pager_offset = '0';
275
- $page_limit = 20;
276
- if ( isset( $_GET['paged'] ) && is_numeric( $_GET['paged'] ) && $_GET['paged'] > 1 ) {
277
- $pager_offset = 20 * ( $_GET['paged'] - 1 );
278
- $page_limit = $pager_offset + 20;
 
279
  }
280
- $html .= '<form action="' . $_SERVER["REQUEST_URI"] . '" method="get">';
281
- $html .= '<p class="search-box">';
282
- $html .= '<input type="hidden" name="page" value="cp-category-permalinks" />';
283
- $html .= '<label class="screen-reader-text" for="custom-permalink-search-input">Search Custom Permalink:</label>';
284
- $html .= '<input type="search" id="custom-permalink-search-input" name="s" value="' . $search_value . '">';
285
- $html .= '<input type="submit" id="search-submit" class="button" value="Search Permalink"></p>';
286
- $html .= '</form>';
287
- $html .= '<form action="' . $_SERVER["REQUEST_URI"] . '" method="post">';
288
- $html .= '<div class="tablenav top">';
289
- $html .= '<div class="alignleft actions bulkactions">
290
- <label for="bulk-action-selector-top" class="screen-reader-text">Select bulk action</label>
291
- <select name="action" id="bulk-action-selector-top">
292
- <option value="-1">' . __( "Bulk Actions", "custom-permalinks" ) . '</option>
293
- <option value="delete">' . __( "Delete Permalinks", "custom-permalinks" ) . '</option>
294
- </select>
295
- <input type="submit" id="doaction" class="button action" value="Apply">
296
- </div>';
297
 
298
- $posts = 0;
299
- $table = get_option( 'custom_permalink_table' );
300
- $count_tags = count( $table );
301
- $pagination_html = '';
302
- if ( isset( $table ) && is_array( $table ) && $count_tags > 0 ) {
303
-
304
- $filtered = array();
305
- if ( $search_value != '' ) {
306
- foreach ( $table as $key => $value ) {
307
- if ( preg_match( '/' . $search_value . '/', $key) ) {
308
- $filtered[$key] = $value;
309
- }
310
- }
311
- $table = $filtered;
312
- $count_tags = count( $table );
313
- }
314
-
315
- $html .= '<h2 class="screen-reader-text">Custom Permalink navigation</h2>';
316
-
317
- $total_pages = ceil( $count_tags / 20 );
318
- if ( isset( $_GET['paged'] ) && is_numeric( $_GET['paged'] )
319
- && $_GET['paged'] > 0 ) {
320
- $pagination_html = $this->cp_pager(
321
- $count_tags, $_GET['paged'], $total_pages
322
  );
323
- if ( $_GET['paged'] > $total_pages ) {
324
- $redirect_uri = explode(
325
- '&paged=' . $_GET['paged'] . '', $_SERVER['REQUEST_URI']
326
- );
327
- header( 'Location: ' . $redirect_uri[0], 301 );
328
- exit();
329
- }
330
- } elseif ( ! isset( $_GET['paged'] ) ) {
331
- $pagination_html = $this->cp_pager( $count_tags, 1, $total_pages );
332
- }
333
 
334
- $html .= $pagination_html;
335
  }
336
- $table_navigation = $this->tablenav_category( $search_permalink );
337
 
338
- $html .= '</div>';
339
- $html .= '<table class="wp-list-table widefat fixed striped posts">
340
- <thead>' . $table_navigation . '</thead>
341
- <tbody>';
342
-
343
- if ( $table && is_array( $table ) && $count_tags > 0 ) {
344
- uasort( $table, array( 'Custom_Permalinks_Admin', 'sort_array' ) );
345
- $i = -1;
346
- foreach ( $table as $permalink => $info ) {
347
- $i++;
348
- if ( $i < $pager_offset )
349
- continue;
350
-
351
- if ( $i >= $page_limit )
352
- break;
353
-
354
- $type = $info['kind'] == 'tag' ? 'post_tag' : 'category';
355
- $term = get_term( $info['id'], $type );
356
- $html .= '<tr valign="top">';
357
- $html .= '<th scope="row" class="check-column">
358
- <input type="checkbox" name="permalink[]" value="' . $info['id'] . '" />
359
- </th>';
360
- $html .= '<td><strong>
361
- <a class="row-title" href="edit-tags.php?action=edit&taxonomy=' . $type . '&tag_ID=' . $info['id'] . ' ">' . $term->name . '</a>
362
- </strong></td>';
363
- $html .= '<td>' . ucwords( $info['kind'] ) . '</td>';
364
- $html .= '<td>
365
- <a href="/' . $permalink . '" target="_blank" title="' . __( "Visit " . $term->name, "custom-permalinks" ) . '">/' . $permalink . '</a>
366
- </td>';
367
- $html .= '</tr>';
368
- }
369
- } else {
370
- $html .= '<tr class="no-items">
371
- <td class="colspanchange" colspan="10">No permalinks found.</td>
372
- </tr>';
373
- }
374
- $html .= '</tbody>
375
- <tfoot>' . $table_navigation . '</tfoot>
376
- </table>';
377
-
378
- $html .= '<div class="tablenav bottom">
379
- <div class="alignleft actions bulkactions">
380
- <label for="bulk-action-selector-bottom" class="screen-reader-text">Select bulk action</label>
381
- <select name="action2" id="bulk-action-selector-bottom">
382
- <option value="-1">' . __( "Bulk Actions", "custom-permalinks" ) . '</option>
383
- <option value="delete">' . __( "Delete Permalinks", "custom-permalinks" ) . '</option>
384
- </select>
385
- <input type="submit" id="doaction2" class="button action" value="Apply">
386
- </div>
387
- ' . $pagination_html . '
388
- </div>';
389
- $html .= '</form></div>';
390
- echo $html;
391
-
392
- add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
393
- }
394
-
395
- /**
396
- * Sort the terms array in desc order using term id
397
- *
398
- * @access private
399
- * @since 1.2
400
- * @return integer
401
- */
402
- private function sort_array( $a, $b ) {
403
- return $b['id'] - $a['id'];
404
- }
405
-
406
- /**
407
- * Return the Navigation row HTML same as Default Posts page for Category
408
- *
409
- * @access private
410
- * @since 1.2
411
- * @return string
412
- */
413
- private function tablenav_category( $search_permalink ) {
414
- $nav = '<tr>
415
- <td id="cb" class="manage-column column-cb check-column">
416
- <label class="screen-reader-text" for="cb-select-all-1">Select All</label>
417
- <input id="cb-select-all-1" type="checkbox">
418
- </td>
419
- <th scope="col" id="title" class="manage-column column-title column-primary">' . __( "Title", "custom-permalinks" ) . '</th>
420
- <th scope="col">' . __( "Type", "custom-permalinks" ) . '</th>
421
- <th scope="col">' . __( "Permalink", "custom-permalinks" ) . '</th>
422
- </tr>';
423
- return $nav;
424
- }
425
-
426
- /**
427
- * Return the Pager HTML
428
- *
429
- * @access private
430
- * @since 1.2
431
- * @return string
432
- */
433
- private function cp_pager( $total_permalinks, $current_pager_value = 1, $total_pager = 0 ) {
434
-
435
- if ( $total_pager == 0 ) return;
436
-
437
- if ( $total_pager == 1 ) {
438
- $pagination_html = '<div class="tablenav-pages one-page">
439
- <span class="displaying-num">' . $total_permalinks . ' items</span>
440
- </div>';
441
- return $pagination_html;
442
- }
443
-
444
- $remove_pager_uri = explode(
445
- '&paged=' . $current_pager_value . '', $_SERVER['REQUEST_URI']
446
- );
447
- $pagination_html = '<div class="tablenav-pages">
448
- <span class="displaying-num">' . $total_permalinks . ' items</span>
449
- <span class="pagination-links">';
450
-
451
- if ( $current_pager_value == 1 ) {
452
- $pagination_html .= '<span class="tablenav-pages-navspan" aria-hidden="true">&laquo; </span>
453
- <span class="tablenav-pages-navspan" aria-hidden="true">&lsaquo; </span>';
454
- } else {
455
- $prev_page = $current_pager_value - 1;
456
- if ( $prev_page == 1 ) {
457
- $pagination_html .= '<span class="tablenav-pages-navspan" aria-hidden="true">&laquo;</span>';
458
- } else {
459
- $pagination_html .= ' <a href="' . $remove_pager_uri[0] . '&paged=1" title="First page" class="first-page">
460
- <span class="screen-reader-text">First page</span>
461
- <span aria-hidden="true">&laquo;</span>
462
- </a> ';
463
- }
464
- $pagination_html .= ' <a href="' . $remove_pager_uri[0] . '&paged=' . $prev_page . '" title="Previous page" class="prev-page">
465
- <span class="screen-reader-text">Previous page</span>
466
- <span aria-hidden="true">&lsaquo;</span>
467
- </a> ';
468
- }
469
-
470
- $pagination_html .= '<span class="paging-input">
471
- <label for="current-page-selector" class="screen-reader-text">Current Page</label>
472
- <input class="current-page" id="current-page-selector" type="text" name="paged" value="' . $current_pager_value . '" size="1" aria-describedby="table-paging" />
473
- <span class="tablenav-paging-text"> of <span class="total-pages">' . $total_pager . ' </span> </span>
474
- </span>';
475
 
476
- if ( $current_pager_value == $total_pager ) {
477
- $pagination_html .= '<span class="tablenav-pages-navspan" aria-hidden="true">&rsaquo; </span>
478
- <span class="tablenav-pages-navspan" aria-hidden="true">&raquo; </span>';
479
- } else {
480
- $next_page = $current_pager_value + 1;
481
- $pagination_html .= ' <a href="' . $remove_pager_uri[0] . '&paged=' . $next_page . '" title="Next page" class="next-page">
482
- <span class="screen-reader-text">Next page</span>
483
- <span aria-hidden="true">&rsaquo;</span>
484
- </a> ';
485
- if ( $total_pager == $next_page) {
486
- $pagination_html .= '<span class="tablenav-pages-navspan" aria-hidden="true">&raquo;</span>';
487
- } else {
488
- $pagination_html .= ' <a href="' . $remove_pager_uri[0] . '&paged=' . $total_pager . '" title="Last page" class="last-page">
489
- <span class="screen-reader-text">Last page</span>
490
- <span aria-hidden="true">&raquo;</span>
491
- </a> ';
492
- }
493
  }
494
- $pagination_html .= '</span></div>';
495
-
496
- return $pagination_html;
497
- }
498
-
499
- /**
500
- * Add About Plugins Page
501
- *
502
- * @access public
503
- * @since 1.2.11
504
- * @return void
505
- */
506
- public function about_plugin() {
507
- require_once(
508
- CUSTOM_PERMALINKS_PATH . 'admin/class-custom-permalinks-about.php'
509
- );
510
- new Custom_Permalinks_About();
511
- add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
512
- }
513
 
514
- /**
515
- * Add Plugin Support and Follow Message in the footer of Admin Pages
516
- *
517
- * @access public
518
- * @since 1.2.11
519
- * @return string
520
- */
521
- public function admin_footer_text() {
522
- $footer_text = sprintf(
523
- __( 'Custom Permalinks version %s by <a href="%s" title="Sami Ahmed Siddiqui Company Website" target="_blank">Sami Ahmed Siddiqui</a> - <a href="%s" title="Support forums" target="_blank">Support forums</a> - Follow on Twitter: <a href="%s" title="Follow Sami Ahmed Siddiqui on Twitter" target="_blank">Sami Ahmed Siddiqui</a>', 'custom-permalinks' ),
524
- CUSTOM_PERMALINKS_PLUGIN_VERSION, 'https://www.yasglobal.com/',
525
- 'https://wordpress.org/support/plugin/custom-permalinks',
526
- 'https://twitter.com/samisiddiqui91'
527
- );
528
- return $footer_text;
529
- }
530
-
531
- /**
532
- * Add About and Premium Settings Page Link on the Plugin Page
533
- * under the Plugin Name.
534
- *
535
- * @access public
536
- * @since 1.2.11
537
- * @return array
538
- */
539
- public function settings_link( $links ) {
540
- $about = sprintf(
541
- __( '<a href="%s" title="About">About</a>', 'custom-permalinks' ),
542
- 'admin.php?page=cp-about-plugins'
543
- );
544
- $premium_support = sprintf(
545
- __( '<a href="%s" title="Premium Support" target="_blank">Premium Support</a>', 'custom-permalinks' ),
546
- 'https://www.custompermalinks.com/#pricing-section'
547
- );
548
- $contact = sprintf(
549
- __( '<a href="%s" title="Contact" target="_blank">Contact</a>', 'custom-permalinks' ),
550
- 'https://www.custompermalinks.com/contact-us/'
551
- );
552
- array_unshift( $links, $contact );
553
- array_unshift( $links, $premium_support );
554
- array_unshift( $links, $about );
555
 
556
- return $links;
557
- }
 
 
 
 
 
 
 
 
558
 
559
- /**
560
- * Add Privacy Policy about the Plugin.
561
- *
562
- * @access public
563
- * @since 1.2.23
564
- * @return void
565
- */
566
- public function cp_privacy_policy() {
567
- if ( ! function_exists( 'wp_add_privacy_policy_content' ) ) {
568
- return;
569
  }
570
-
571
- $content = sprintf(
572
- __( 'This plugin doesn\'t collect/store any user related information.
573
-
574
- To have any kind of further query please feel free to
575
- <a href="%s" target="_blank">contact us</a>.',
576
- 'custom-permalinks' ),
577
- 'https://www.custompermalinks.com/contact-us/'
578
- );
579
-
580
- wp_add_privacy_policy_content(
581
- 'Custom Permalinks',
582
- wp_kses_post( wpautop( $content, false ) )
583
- );
584
- }
585
  }
1
  <?php
2
  /**
3
+ * @package CustomPermalinks
4
  */
5
 
6
+ class Custom_Permalinks_Admin
7
+ {
8
+
9
+ /**
10
+ * Initializes WordPress hooks.
11
+ */
12
+ function __construct()
13
+ {
14
+ add_action( 'admin_menu', array( $this, 'admin_menu' ) );
15
+ add_filter( 'plugin_action_links_' . CUSTOM_PERMALINKS_BASENAME,
16
+ array( $this, 'settings_link' )
17
+ );
18
+ add_action( 'admin_init', array( $this, 'privacy_policy' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
+ /**
22
+ * Added Pages in Menu for Settings.
23
+ *
24
+ * @since 1.2.0
25
+ * @access public
26
+ */
27
+ public function admin_menu()
28
+ {
29
+ add_menu_page( 'Custom Permalinks', 'Custom Permalinks',
30
+ 'cp_view_post_permalinks', 'cp-post-permalinks',
31
+ array( $this,'post_permalinks_page' ), 'dashicons-admin-links'
32
  );
33
+ add_submenu_page( 'cp-post-permalinks', 'PostTypes Permalinks',
34
+ 'PostTypes Permalinks', 'cp_view_post_permalinks',
35
+ 'cp-post-permalinks', array( $this, 'post_permalinks_page' )
36
+ );
37
+ add_submenu_page( 'cp-post-permalinks', 'Taxonomies Permalinks',
38
+ 'Taxonomies Permalinks', 'cp_view_category_permalinks',
39
+ 'cp-category-permalinks', array( $this, 'taxonomy_permalinks_page' )
40
+ );
41
+ add_submenu_page( 'cp-post-permalinks', 'About Custom Permalinks', 'About',
42
+ 'install_plugins', 'cp-about-plugins', array( $this, 'about_plugin' )
43
  );
 
 
 
44
  }
 
 
 
45
 
46
+ /**
47
+ * Calls another Function which shows the PostTypes Permalinks Page.
48
+ *
49
+ * @since 1.2.0
50
+ * @access public
51
+ */
52
+ public function post_permalinks_page()
53
+ {
54
+ require_once CUSTOM_PERMALINKS_PATH . 'admin/class-custom-permalinks-posttypes.php';
55
+ new Custom_Permalinks_PostTypes();
56
+
57
+ add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
 
 
 
 
 
 
 
 
 
 
 
58
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
+ /**
61
+ * Calls another Function which shows the Taxonomies Permalinks Page.
62
+ *
63
+ * @since 1.2.0
64
+ * @access public
65
+ */
66
+ public function taxonomy_permalinks_page()
67
+ {
68
+ require_once CUSTOM_PERMALINKS_PATH . 'admin/class-custom-permalinks-taxonomies.php';
69
+ new Custom_Permalinks_Taxonomies();
70
+
71
+ add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
 
 
 
 
 
 
 
72
  }
 
 
73
 
74
+ /**
75
+ * Add About Plugins Page.
76
+ *
77
+ * @since 1.2.11
78
+ * @access public
79
+ */
80
+ public function about_plugin()
81
+ {
82
+ require_once CUSTOM_PERMALINKS_PATH . 'admin/class-custom-permalinks-about.php';
83
+ new Custom_Permalinks_About();
84
+
85
+ add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
86
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
+ /**
89
+ * Add Plugin Support and Follow Message in the footer of Admin Pages.
90
+ *
91
+ * @since 1.2.11
92
+ * @access public
93
+ *
94
+ * @return string Shows version, website link and twitter.
95
+ */
96
+ public function admin_footer_text()
97
+ {
98
+ $footer_text = sprintf(
99
+ __( 'Custom Permalinks version %s by <a href="%s" title="Sami Ahmed Siddiqui Company Website" target="_blank">Sami Ahmed Siddiqui</a> - <a href="%s" title="Support forums" target="_blank">Support forums</a> - Follow on Twitter: <a href="%s" title="Follow Sami Ahmed Siddiqui on Twitter" target="_blank">Sami Ahmed Siddiqui</a>',
100
+ 'custom-permalinks'
101
+ ),
102
+ CUSTOM_PERMALINKS_PLUGIN_VERSION, 'https://www.yasglobal.com/',
103
+ 'https://wordpress.org/support/plugin/custom-permalinks',
104
+ 'https://twitter.com/samisiddiqui91'
 
 
 
 
 
 
 
105
  );
 
 
 
 
 
 
 
 
 
 
106
 
107
+ return $footer_text;
108
  }
 
109
 
110
+ /**
111
+ * Add About and Premium Settings Page Link on the Plugin Page under the
112
+ * Plugin Name.
113
+ *
114
+ * @since 1.2.11
115
+ * @access public
116
+ *
117
+ * @param array $links Contains the Plugin Basic Link (Activate/Deactivate/Delete).
118
+ *
119
+ * @return array Plugin Basic Links and added some custome link for Settings,
120
+ * Contact, and About.
121
+ */
122
+ public function settings_link( $links )
123
+ {
124
+ $about = sprintf( __(
125
+ '<a href="%s" title="About">About</a>', 'custom-permalinks'
126
+ ),
127
+ 'admin.php?page=cp-about-plugins'
128
+ );
129
+ $premium_support = sprintf( __(
130
+ '<a href="%s" title="Premium Support" target="_blank">Premium Support</a>',
131
+ 'custom-permalinks'
132
+ ),
133
+ 'https://www.custompermalinks.com/#pricing-section'
134
+ );
135
+ $contact = sprintf( __(
136
+ '<a href="%s" title="Contact" target="_blank">Contact</a>',
137
+ 'custom-permalinks'
138
+ ),
139
+ 'https://www.custompermalinks.com/contact-us/'
140
+ );
141
+ array_unshift( $links, $contact );
142
+ array_unshift( $links, $premium_support );
143
+ array_unshift( $links, $about );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
145
+ return $links;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
 
148
+ /**
149
+ * Add Privacy Policy about the Plugin.
150
+ *
151
+ * @since 1.2.23
152
+ * @access public
153
+ */
154
+ public function privacy_policy()
155
+ {
156
+ if ( ! function_exists( 'wp_add_privacy_policy_content' ) ) {
157
+ return;
158
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
 
160
+ $content = sprintf(
161
+ __(
162
+ 'This plugin collect information about the site like URL, WordPress version etc.' .
163
+ ' This plugin doesn\'t collect any user related information.' .
164
+ ' To have any kind of further query please feel free to' .
165
+ ' <a href="%s" target="_blank">contact us</a>.',
166
+ 'custom-permalinks'
167
+ ),
168
+ 'https://www.custompermalinks.com/contact-us/'
169
+ );
170
 
171
+ wp_add_privacy_policy_content( 'Custom Permalinks',
172
+ wp_kses_post( wpautop( $content, false ) )
173
+ );
 
 
 
 
 
 
 
174
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  }
admin/class-custom-permalinks-pager.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package CustomPermalinks
4
+ */
5
+
6
+ class Custom_Permalinks_Pager
7
+ {
8
+
9
+ /**
10
+ * Return the Pager HTML.
11
+ *
12
+ * @since 1.2.0
13
+ * @access public
14
+ *
15
+ * @param int $total_permalinks No. of total results found.
16
+ * @param int $current_pager_value Optional. Current Page. 1.
17
+ * @param int $total_pager Optional. Total no. of pages. 0.
18
+ *
19
+ * @return string Pagination HTML if pager exist.
20
+ */
21
+ public function get_pagination( $total_permalinks, $current_pager_value = 1,
22
+ $total_pager = 0
23
+ ) {
24
+ if ( 0 == $total_pager ) {
25
+ return;
26
+ }
27
+
28
+ if ( 1 == $total_pager ) {
29
+ $pagination_html = '<div class="tablenav-pages one-page">' .
30
+ '<span class="displaying-num">' .
31
+ $total_permalinks . ' items' .
32
+ '</span>' .
33
+ '</div>';
34
+
35
+ return $pagination_html;
36
+ }
37
+
38
+ $remove_pager_uri = array();
39
+ if ( isset( $_SERVER['REQUEST_URI'] ) ) {
40
+ $remove_pager_uri = explode(
41
+ '&paged=' . $current_pager_value . '', $_SERVER['REQUEST_URI']
42
+ );
43
+ }
44
+ $pagination_html = '<div class="tablenav-pages">' .
45
+ '<span class="displaying-num">' .
46
+ $total_permalinks . ' items' .
47
+ '</span>' .
48
+ '<span class="pagination-links">';
49
+
50
+ if ( 1 == $current_pager_value ) {
51
+ $pagination_html .= '<span class="tablenav-pages-navspan" aria-hidden="true">&laquo; </span>' .
52
+ '<span class="tablenav-pages-navspan" aria-hidden="true">&lsaquo; </span>';
53
+ } else {
54
+ $prev_page = $current_pager_value - 1;
55
+ if ( 1 == $prev_page ) {
56
+ $pagination_html .= '<span class="tablenav-pages-navspan" aria-hidden="true">&laquo;</span>';
57
+ } else {
58
+ $pagination_html .= ' <a href="' . $remove_pager_uri[0] . '&paged=1" title="First page" class="first-page">' .
59
+ '<span class="screen-reader-text">First page</span>' .
60
+ '<span aria-hidden="true">&laquo;</span>' .
61
+ '</a> ';
62
+ }
63
+ $pagination_html .= ' <a href="' . $remove_pager_uri[0] . '&paged=' . $prev_page . '" title="Previous page" class="prev-page">' .
64
+ '<span class="screen-reader-text">Previous page</span>' .
65
+ '<span aria-hidden="true">&lsaquo;</span>' .
66
+ '</a> ';
67
+ }
68
+
69
+ $pagination_html .= '<span class="paging-input">' .
70
+ '<label for="current-page-selector" class="screen-reader-text">Current Page</label>' .
71
+ '<input class="current-page" id="current-page-selector" type="text" name="paged" value="' . $current_pager_value . '" size="1" aria-describedby="table-paging" />' .
72
+ '<span class="tablenav-paging-text"> of <span class="total-pages">' . $total_pager . ' </span> </span>' .
73
+ '</span>';
74
+
75
+ if ( $current_pager_value == $total_pager ) {
76
+ $pagination_html .= '<span class="tablenav-pages-navspan" aria-hidden="true">&rsaquo; </span>' .
77
+ '<span class="tablenav-pages-navspan" aria-hidden="true">&raquo; </span>';
78
+ } else {
79
+ $next_page = $current_pager_value + 1;
80
+ $pagination_html .= ' <a href="' . $remove_pager_uri[0] . '&paged=' . $next_page . '" title="Next page" class="next-page">' .
81
+ '<span class="screen-reader-text">Next page</span>' .
82
+ '<span aria-hidden="true">&rsaquo;</span>' .
83
+ '</a> ';
84
+ if ( $total_pager == $next_page ) {
85
+ $pagination_html .= '<span class="tablenav-pages-navspan" aria-hidden="true">&raquo;</span>';
86
+ } else {
87
+ $pagination_html .= ' <a href="' . $remove_pager_uri[0] . '&paged=' . $total_pager . '" title="Last page" class="last-page">' .
88
+ '<span class="screen-reader-text">Last page</span>' .
89
+ '<span aria-hidden="true">&raquo;</span>' .
90
+ '</a> ';
91
+ }
92
+ }
93
+ $pagination_html .= '</span></div>';
94
+
95
+ return $pagination_html;
96
+ }
97
+ }
admin/class-custom-permalinks-posttypes.php ADDED
@@ -0,0 +1,317 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package CustomPermalinks
4
+ */
5
+
6
+ class Custom_Permalinks_PostTypes
7
+ {
8
+
9
+ /**
10
+ * Call Post Permalinks Function.
11
+ */
12
+ function __construct()
13
+ {
14
+ $this->post_permalinks();
15
+ }
16
+
17
+ /**
18
+ * Return the Navigation row HTML same as Default Posts page for PostTypes.
19
+ *
20
+ * @since 1.2.0
21
+ * @access private
22
+ *
23
+ * @param string $order_by_class Class either asc or desc.
24
+ * @param string $order_by set orderby for sorting.
25
+ * @param string $search_permalink Permalink which has been searched or an empty string.
26
+ *
27
+ * @return string table row according to the provided params.
28
+ */
29
+ private function post_nav( $order_by_class, $order_by, $search_permalink )
30
+ {
31
+ $post_nav = '<tr>' .
32
+ '<td id="cb" class="manage-column column-cb check-column">' .
33
+ '<label class="screen-reader-text" for="cb-select-all-1">Select All</label>' .
34
+ '<input id="cb-select-all-1" type="checkbox">' .
35
+ '</td>' .
36
+ '<th scope="col" id="title" class="manage-column column-title column-primary sortable ' . $order_by_class . '">' .
37
+ '<a href="/wp-admin/admin.php?page=cp-post-permalinks&amp;orderby=title&amp;order=' . $order_by . $search_permalink . '">' .
38
+ '<span>' . __( "Title", "custom-permalinks" ) . '</span>' .
39
+ '<span class="sorting-indicator"></span>' .
40
+ '</a>' .
41
+ '</th>' .
42
+ '<th scope="col">' . __( "Type", "custom-permalinks" ) . '</th>' .
43
+ '<th scope="col">' . __( "Permalink", "custom-permalinks" ) . '</th>' .
44
+ '</tr>';
45
+
46
+ return $post_nav;
47
+ }
48
+
49
+ /**
50
+ * Shows all the Permalinks created by using this Plugin with Pager and Search
51
+ * Functionality of Posts/Pages.
52
+ *
53
+ * @since 1.2.0
54
+ * @access private
55
+ */
56
+ private function post_permalinks()
57
+ {
58
+ global $wpdb;
59
+
60
+ $error = '';
61
+ $filter_options = '';
62
+ $filter_permalink = '';
63
+ $home_url = home_url();
64
+ $post_html = '';
65
+ $post_action = filter_input( INPUT_POST, 'action' );
66
+ $post_action2 = filter_input( INPUT_POST, 'action2' );
67
+ $post_permalinks = filter_input( INPUT_POST, 'permalink', FILTER_DEFAULT,
68
+ FILTER_REQUIRE_ARRAY
69
+ );
70
+ $request_uri = '';
71
+ $search_permalink = '';
72
+ $site_url = site_url();
73
+ $user_id = get_current_user_id();
74
+
75
+ if ( isset( $_SERVER['REQUEST_URI'] ) ) {
76
+ $request_uri = $_SERVER['REQUEST_URI'];
77
+ }
78
+
79
+ // Handle Bulk Operations
80
+ if ( (
81
+ ( isset( $post_action ) && 'delete' === $post_action )
82
+ || ( isset( $post_action2 ) && 'delete' === $post_action2 )
83
+ )
84
+ && check_admin_referer( 'custom-permalinks-post_' . $user_id,
85
+ '_custom_permalinks_post_nonce'
86
+ )
87
+ ) {
88
+ if ( isset( $post_permalinks ) && ! empty( $post_permalinks ) ) {
89
+ $post_ids = $post_permalinks;
90
+ if ( is_array( $post_ids ) && 0 < count( $post_ids ) ) {
91
+ foreach ( $post_ids as $post_id ) {
92
+ if ( is_numeric( $post_id ) ) {
93
+ delete_post_meta( $post_id, 'custom_permalink' );
94
+ }
95
+ }
96
+ } else {
97
+ $error = '<div id="message" class="error">' .
98
+ '<p>' .
99
+ __( 'Please select permalinks which you like to be deleted.',
100
+ 'custom-permalinks'
101
+ ) .
102
+ '</p>' .
103
+ '</div>';
104
+ }
105
+ } else {
106
+ $error = '<div id="message" class="error">' .
107
+ '<p>' .
108
+ __( 'There is some error to proceed your request. Please retry with your request or contact to the plugin author.',
109
+ 'custom-permalinks'
110
+ ) .
111
+ '</p>' .
112
+ '</div>';
113
+ }
114
+ }
115
+ $post_html .= '<div class="wrap">' .
116
+ '<h1 class="wp-heading-inline">' .
117
+ __( 'PostTypes Permalinks', 'custom-permalinks' ) .
118
+ '</h1>' .
119
+ $error;
120
+
121
+ $get_paged = filter_input( INPUT_GET, 'paged' );
122
+ $get_order = filter_input( INPUT_GET, 'order' );
123
+ $get_order_by = filter_input( INPUT_GET, 'orderby' );
124
+ $order_by = 'asc';
125
+ $order_by_class = 'desc';
126
+ $page_limit = 'LIMIT 0, 20';
127
+ $search_input = filter_input( INPUT_GET, 's' );
128
+ $search_value = '';
129
+ $sorting_by = 'ORDER By p.ID DESC';
130
+
131
+ if ( $search_input
132
+ && check_admin_referer( 'custom-permalinks-post_' . $user_id,
133
+ '_custom_permalinks_post_nonce'
134
+ )
135
+ ) {
136
+ $filter_permalink = 'AND pm.meta_value LIKE "%' . $search_input . '%"';
137
+ $search_permalink = '&s=' . $search_input . '';
138
+ $search_value = ltrim( htmlspecialchars( $search_input ), '/' );
139
+ $post_html .= '<span class="subtitle">Search results for "' . $search_value . '"</span>';
140
+ }
141
+
142
+ if ( $get_paged && is_numeric( $get_paged ) && 1 < $get_paged ) {
143
+ $pager = 20 * ( $get_paged - 1 );
144
+ $page_limit = 'LIMIT ' . $pager . ', 20';
145
+ }
146
+
147
+ if ( $get_order_by && 'title' === $get_order_by ) {
148
+ $filter_options .= '<input type="hidden" name="orderby" value="title" />';
149
+ if ( $get_order && 'desc' === $get_order ) {
150
+ $sorting_by = 'ORDER By p.post_title DESC';
151
+ $order_by = 'asc';
152
+ $order_by_class = 'desc';
153
+ $filter_options .= '<input type="hidden" name="order" value="desc" />';
154
+ } else {
155
+ $sorting_by = 'ORDER By p.post_title';
156
+ $order_by = 'desc';
157
+ $order_by_class = 'asc';
158
+ $filter_options .= '<input type="hidden" name="order" value="asc" />';
159
+ }
160
+ }
161
+
162
+ $count_query = "SELECT COUNT(p.ID) AS total_permalinks FROM $wpdb->posts AS p LEFT JOIN $wpdb->postmeta AS pm ON (p.ID = pm.post_id) WHERE pm.meta_key = 'custom_permalink' AND pm.meta_value != '' " . $filter_permalink . "";
163
+ $count_posts = $wpdb->get_row( $count_query );
164
+ $post_nonce = wp_nonce_field(
165
+ 'custom-permalinks-post_' . $user_id, '_custom_permalinks_post_nonce',
166
+ true, false
167
+ );
168
+
169
+ $post_html .= '<form action="' . $site_url . $request_uri . '" method="get">' .
170
+ '<p class="search-box">' .
171
+ '<input type="hidden" name="page" value="cp-post-permalinks" />' .
172
+ $post_nonce .
173
+ $filter_options .
174
+ '<label class="screen-reader-text" for="custom-permalink-search-input">Search Custom Permalink:</label>' .
175
+ '<input type="search" id="custom-permalink-search-input" name="s" value="' . $search_value . '">' .
176
+ '<input type="submit" id="search-submit" class="button" value="Search Permalink"></p>' .
177
+ '</form>' .
178
+ '<form action="' . $site_url . $request_uri . '" method="post">' .
179
+ '<div class="tablenav top">' .
180
+ '<div class="alignleft actions bulkactions">' .
181
+ '<label for="bulk-action-selector-top" class="screen-reader-text">Select bulk action</label>' .
182
+ $post_nonce .
183
+ '<select name="action" id="bulk-action-selector-top">' .
184
+ '<option value="-1">' .
185
+ __( "Bulk Actions", "custom-permalinks" ) .
186
+ '</option>' .
187
+ '<option value="delete">' .
188
+ __( "Delete Permalinks", "custom-permalinks" ) .
189
+ '</option>' .
190
+ '</select>' .
191
+ '<input type="submit" id="doaction" class="button action" value="Apply">' .
192
+ '</div>';
193
+
194
+ $posts = 0;
195
+ $pagination_html = '';
196
+ if ( isset( $count_posts->total_permalinks )
197
+ && 0 < $count_posts->total_permalinks
198
+ ) {
199
+ include_once CUSTOM_PERMALINKS_PATH . 'admin/class-custom-permalinks-pager.php';
200
+
201
+ $cp_pager = new Custom_Permalinks_Pager();
202
+ $post_html .= '<h2 class="screen-reader-text">Custom Permalink navigation</h2>';
203
+
204
+ $query = "SELECT p.ID, p.post_title, p.post_type, pm.meta_value FROM $wpdb->posts AS p LEFT JOIN $wpdb->postmeta AS pm ON (p.ID = pm.post_id) WHERE pm.meta_key = 'custom_permalink' AND pm.meta_value != '' " . $filter_permalink . " " . $sorting_by . " " . $page_limit . "";
205
+ $posts = $wpdb->get_results( $query );
206
+
207
+ $total_pages = ceil( $count_posts->total_permalinks / 20 );
208
+ if ( $get_paged && is_numeric( $get_paged ) && 0 < $get_paged ) {
209
+ $pagination_html = $cp_pager->get_pagination(
210
+ $count_posts->total_permalinks, $get_paged, $total_pages
211
+ );
212
+ if ( $get_paged > $total_pages ) {
213
+ $redirect_uri = explode( '&paged=' . $get_paged . '',
214
+ $request_uri
215
+ );
216
+
217
+ wp_safe_redirect( $redirect_uri[0], 301 );
218
+ exit;
219
+ }
220
+ } elseif ( ! $get_paged ) {
221
+ $pagination_html = $cp_pager->get_pagination(
222
+ $count_posts->total_permalinks, 1, $total_pages
223
+ );
224
+ }
225
+
226
+ $post_html .= $pagination_html;
227
+ }
228
+ $table_navigation = $this->post_nav( $order_by_class, $order_by,
229
+ $search_permalink
230
+ );
231
+
232
+ $post_html .= '</div>';
233
+ $post_html .= '<table class="wp-list-table widefat fixed striped posts">' .
234
+ '<thead>' . $table_navigation . '</thead>' .
235
+ '<tbody>';
236
+ if ( 0 != $posts && ! empty( $posts ) ) {
237
+ $cp_frontend = new Custom_Permalinks_Frontend();
238
+ if ( class_exists( 'SitePress' ) ) {
239
+ $wpml_lang_format = apply_filters( 'wpml_setting', 0,
240
+ 'language_negotiation_type'
241
+ );
242
+
243
+ if ( 1 === intval( $wpml_lang_format ) ) {
244
+ $home_url = $site_url;
245
+ }
246
+ }
247
+
248
+ foreach ( $posts as $post ) {
249
+ $custom_permalink = '/' . $post->meta_value;
250
+ $post_type = 'post';
251
+ if ( isset( $post->post_type ) ) {
252
+ $post_type = $post->post_type;
253
+ }
254
+
255
+ $language_code = apply_filters( 'wpml_element_language_code', null,
256
+ array(
257
+ 'element_id' => $post->ID,
258
+ 'element_type' => $post_type
259
+ )
260
+ );
261
+
262
+ $permalink = $cp_frontend->wpml_permalink_filter( $custom_permalink,
263
+ $language_code
264
+ );
265
+ $permalink = $cp_frontend->remove_double_slash( $permalink );
266
+ $perm_text = str_replace( $home_url, '', $permalink );
267
+
268
+ $post_html .= '<tr valign="top">' .
269
+ '<th scope="row" class="check-column">' .
270
+ '<input type="checkbox" name="permalink[]" value="' . $post->ID . '" />' .
271
+ '</th>' .
272
+ '<td>' .
273
+ '<strong>' .
274
+ '<a class="row-title" href="' . $site_url . '/wp-admin/post.php?action=edit&post=' . $post->ID . '">' .
275
+ $post->post_title .
276
+ '</a>' .
277
+ '</strong>' .
278
+ '</td>' .
279
+ '<td>' . ucwords( $post->post_type ) . '</td>' .
280
+ '<td>' .
281
+ '<a href="' . $permalink . '" target="_blank" title="' . __( "Visit " . $post->post_title, "custom-permalinks" ) . '">' .
282
+ $perm_text .
283
+ '</a>' .
284
+ '</td>' .
285
+ '</tr>';
286
+ }
287
+ } else {
288
+ $post_html .= '<tr class="no-items">' .
289
+ '<td class="colspanchange" colspan="4">' .
290
+ __( "No permalinks found.", "custom-permalinks" ) .
291
+ '</td>' .
292
+ '</tr>';
293
+ }
294
+ $post_html .= '</tbody>' .
295
+ '<tfoot>' . $table_navigation . '</tfoot>' .
296
+ '</table>';
297
+
298
+ $post_html .= '<div class="tablenav bottom">' .
299
+ '<div class="alignleft actions bulkactions">' .
300
+ '<label for="bulk-action-selector-bottom" class="screen-reader-text">Select bulk action</label>' .
301
+ '<select name="action2" id="bulk-action-selector-bottom">' .
302
+ '<option value="-1">'
303
+ . __( "Bulk Actions", "custom-permalinks" ) .
304
+ '</option>' .
305
+ '<option value="delete">' .
306
+ __( "Delete Permalinks", "custom-permalinks" ) .
307
+ '</option>' .
308
+ '</select>' .
309
+ '<input type="submit" id="doaction2" class="button action" value="Apply">' .
310
+ '</div>' .
311
+ $pagination_html .
312
+ '</div>' .
313
+ '</form></div>';
314
+
315
+ echo $post_html;
316
+ }
317
+ }
admin/class-custom-permalinks-taxonomies.php ADDED
@@ -0,0 +1,294 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package CustomPermalinks
4
+ */
5
+
6
+ class Custom_Permalinks_Taxonomies
7
+ {
8
+
9
+ /**
10
+ * Call Taxonomy Permalinks Function.
11
+ */
12
+ function __construct()
13
+ {
14
+ $this->taxonomies_permalinks();
15
+ }
16
+
17
+ /**
18
+ * Return the Navigation row HTML same as Default Posts page for Category.
19
+ *
20
+ * @since 1.2.0
21
+ * @access private
22
+ *
23
+ * @return string table row according to the provided params.
24
+ */
25
+ private function taxonomy_nav()
26
+ {
27
+ $navigation = '<tr>' .
28
+ '<td id="cb" class="manage-column column-cb check-column">' .
29
+ '<label class="screen-reader-text" for="cb-select-all-1">Select All</label>' .
30
+ '<input id="cb-select-all-1" type="checkbox">' .
31
+ '</td>' .
32
+ '<th scope="col" id="title" class="manage-column column-title column-primary">' .
33
+ __( "Title", "custom-permalinks" ) .
34
+ '</th>' .
35
+ '<th scope="col">' . __( "Type", "custom-permalinks" ) . '</th>' .
36
+ '<th scope="col">' . __( "Permalink", "custom-permalinks" ) . '</th>' .
37
+ '</tr>';
38
+
39
+ return $navigation;
40
+ }
41
+
42
+ /**
43
+ * Sort the terms array in desc order using term id.
44
+ *
45
+ * @since 1.2.0
46
+ * @access public
47
+ *
48
+ * @return int
49
+ */
50
+ public function sort_array( $comp1, $comp2 )
51
+ {
52
+ return $comp2['id'] - $comp1['id'];
53
+ }
54
+
55
+ /**
56
+ * Shows all the Permalinks created by using this Plugin with Pager and
57
+ * Search Functionality of Category/Tags.
58
+ *
59
+ * @since 1.2.0
60
+ * @access private
61
+ */
62
+ private function taxonomies_permalinks()
63
+ {
64
+ $home_url = home_url();
65
+ $page_html = '';
66
+ $request_uri = '';
67
+ $site_url = site_url();
68
+ $term_action = filter_input( INPUT_POST, 'action' );
69
+ $term_action2 = filter_input( INPUT_POST, 'action2' );
70
+ $term_permalinks = filter_input( INPUT_POST, 'permalink',
71
+ FILTER_DEFAULT, FILTER_REQUIRE_ARRAY
72
+ );
73
+ $user_id = get_current_user_id();
74
+
75
+ if ( isset( $_SERVER['REQUEST_URI'] ) ) {
76
+ $request_uri = $_SERVER['REQUEST_URI'];
77
+ }
78
+
79
+ // Handle Bulk Operations
80
+ if ( (
81
+ ( isset( $term_action ) && 'delete' === $term_action )
82
+ || ( isset( $term_action2 ) && 'delete' === $term_action2 )
83
+ )
84
+ && check_admin_referer( 'custom-permalinks-term_' . $user_id,
85
+ '_custom_permalinks_term_nonce'
86
+ )
87
+ ) {
88
+ if ( isset( $term_permalinks ) && ! empty( $term_permalinks ) ) {
89
+ $data = get_option( 'custom_permalink_table' );
90
+ if ( isset( $data ) && is_array( $data ) ) {
91
+ $loopCount = 0;
92
+ foreach ( $data as $link => $info ) {
93
+ if ( in_array( $info['id'], $term_permalinks ) ) {
94
+ unset( $data[$link] );
95
+ unset( $term_permalinks[$loopCount] );
96
+ if ( ! is_array( $term_permalinks )
97
+ || empty( $term_permalinks )
98
+ ) {
99
+ break;
100
+ }
101
+ }
102
+ $loopCount += 1;
103
+ }
104
+ }
105
+
106
+ update_option( 'custom_permalink_table', $data );
107
+ }
108
+ }
109
+ $page_html .= '<div class="wrap">' .
110
+ '<h1 class="wp-heading-inline">' .
111
+ __( 'Taxonomies Permalinks', 'custom-permalinks' ) .
112
+ '</h1>';
113
+
114
+ $get_paged = filter_input( INPUT_GET, 'paged' );
115
+ $page_limit = 20;
116
+ $pager_offset = '0';
117
+ $search_input = filter_input( INPUT_GET, 's' );
118
+ $search_value = '';
119
+ $term_nonce = wp_nonce_field(
120
+ 'custom-permalinks-term_' . $user_id, '_custom_permalinks_term_nonce',
121
+ true, false
122
+ );
123
+
124
+ if ( $search_input && ! empty( $search_input )
125
+ && check_admin_referer( 'custom-permalinks-term_' . $user_id,
126
+ '_custom_permalinks_term_nonce'
127
+ )
128
+ ) {
129
+ $search_value = ltrim( htmlspecialchars( $search_input ), '/' );
130
+ $page_html .= '<span class="subtitle">Search results for "' . $search_value . '"</span>';
131
+ }
132
+
133
+ if ( $get_paged && is_numeric( $get_paged ) && 1 < $get_paged ) {
134
+ $pager_offset = 20 * ( $get_paged - 1 );
135
+ $page_limit = $pager_offset + 20;
136
+ }
137
+
138
+ $page_html .= '<form action="' . $site_url . $request_uri . '" method="get">' .
139
+ '<p class="search-box">' .
140
+ '<input type="hidden" name="page" value="cp-category-permalinks" />' .
141
+ $term_nonce .
142
+ '<label class="screen-reader-text" for="custom-permalink-search-input">Search Custom Permalink:</label>' .
143
+ '<input type="search" id="custom-permalink-search-input" name="s" value="' . $search_value . '">' .
144
+ '<input type="submit" id="search-submit" class="button" value="Search Permalink"></p>' .
145
+ '</form>' .
146
+ '<form action="' . $site_url . $request_uri . '" method="post">' .
147
+ '<div class="tablenav top">' .
148
+ '<div class="alignleft actions bulkactions">' .
149
+ '<label for="bulk-action-selector-top" class="screen-reader-text">Select bulk action</label>' .
150
+ $term_nonce .
151
+ '<select name="action" id="bulk-action-selector-top">' .
152
+ '<option value="-1">' . __( "Bulk Actions", "custom-permalinks" ) . '</option>' .
153
+ '<option value="delete">' . __( "Delete Permalinks", "custom-permalinks" ) . '</option>' .
154
+ '</select>' .
155
+ '<input type="submit" id="doaction" class="button action" value="Apply">' .
156
+ '</div>';
157
+
158
+ $table = get_option( 'custom_permalink_table' );
159
+ $count_tags = 0;
160
+ $pagination_html = '';
161
+ if ( isset( $table ) && is_array( $table ) ) {
162
+ $count_tags = count( $table );
163
+ }
164
+
165
+ if ( 0 < $count_tags ) {
166
+ include_once CUSTOM_PERMALINKS_PATH . 'admin/class-custom-permalinks-pager.php';
167
+
168
+ $cp_pager = new Custom_Permalinks_Pager();
169
+ $filtered = array();
170
+ if ( '' != $search_value ) {
171
+ foreach ( $table as $key => $value ) {
172
+ if ( preg_match( '/' . $search_value . '/', $key) ) {
173
+ $filtered[$key] = $value;
174
+ }
175
+ }
176
+ $table = $filtered;
177
+ $count_tags = count( $table );
178
+ }
179
+
180
+ $page_html .= '<h2 class="screen-reader-text">Custom Permalink navigation</h2>';
181
+
182
+ $total_pages = ceil( $count_tags / 20 );
183
+ if ( $get_paged && is_numeric( $get_paged ) && 0 < $get_paged ) {
184
+ $pagination_html = $cp_pager->get_pagination(
185
+ $count_tags, $get_paged, $total_pages
186
+ );
187
+ if ( $get_paged > $total_pages ) {
188
+ $redirect_uri = explode( '&paged=' . $get_paged . '',
189
+ $request_uri
190
+ );
191
+
192
+ wp_safe_redirect( $redirect_uri[0], 301 );
193
+ exit;
194
+ }
195
+ } elseif ( ! isset( $get_paged ) ) {
196
+ $pagination_html = $cp_pager->get_pagination( $count_tags, 1,
197
+ $total_pages
198
+ );
199
+ }
200
+
201
+ $page_html .= $pagination_html;
202
+ }
203
+ $table_navigation = $this->taxonomy_nav();
204
+
205
+ $page_html .= '</div>' .
206
+ '<table class="wp-list-table widefat fixed striped posts">' .
207
+ '<thead>' . $table_navigation . '</thead>' .
208
+ '<tbody>';
209
+
210
+ if ( $table && is_array( $table ) && 0 < $count_tags ) {
211
+ $cp_frontend = new Custom_Permalinks_Frontend();
212
+ if ( class_exists( 'SitePress' ) ) {
213
+ $wpml_lang_format = apply_filters( 'wpml_setting', 0,
214
+ 'language_negotiation_type'
215
+ );
216
+
217
+ if ( 1 === intval( $wpml_lang_format ) ) {
218
+ $home_url = $site_url;
219
+ }
220
+ }
221
+
222
+ uasort( $table, array( $this, 'sort_array' ) );
223
+ $loopCount = -1;
224
+ foreach ( $table as $permalink => $info ) {
225
+ $loopCount += 1;
226
+ if ( $loopCount < $pager_offset ) {
227
+ continue;
228
+ }
229
+
230
+ if ( $loopCount >= $page_limit ) {
231
+ break;
232
+ }
233
+
234
+ $type = 'category';
235
+ if ( 'tag' == $info['kind'] ) {
236
+ $type = 'post_tag';
237
+ }
238
+
239
+ $language_code = apply_filters( 'wpml_element_language_code',
240
+ null, array(
241
+ 'element_id' => $info['id'],
242
+ 'element_type' => $type
243
+ )
244
+ );
245
+
246
+ $permalink = $cp_frontend->wpml_permalink_filter( $permalink,
247
+ $language_code
248
+ );
249
+ $permalink = $cp_frontend->remove_double_slash( $permalink );
250
+ $perm_text = str_replace( $home_url, '', $permalink );
251
+
252
+ $term = get_term( $info['id'], $type );
253
+ $page_html .= '<tr valign="top">' .
254
+ '<th scope="row" class="check-column">' .
255
+ '<input type="checkbox" name="permalink[]" value="' . $info['id'] . '" />' .
256
+ '</th>' .
257
+ '<td><strong>' .
258
+ '<a class="row-title" href="' . $site_url . '/wp-admin/edit-tags.php?action=edit&taxonomy=' . $type . '&tag_ID=' . $info['id'] . ' ">' .
259
+ $term->name .
260
+ '</a>' .
261
+ '</strong></td>' .
262
+ '<td>' . ucwords( $info['kind'] ) . '</td>' .
263
+ '<td>' .
264
+ '<a href="' . $permalink . '" target="_blank" title="' . __( "Visit " . $term->name, "custom-permalinks" ) . '">' .
265
+ $perm_text .
266
+ '</a>' .
267
+ '</td>' .
268
+ '</tr>';
269
+ }
270
+ } else {
271
+ $page_html .= '<tr class="no-items">' .
272
+ '<td class="colspanchange" colspan="4">' . __( "No permalinks found.", "custom-permalinks" ) . '</td>' .
273
+ '</tr>';
274
+ }
275
+ $page_html .= '</tbody>' .
276
+ '<tfoot>' . $table_navigation . '</tfoot>' .
277
+ '</table>';
278
+
279
+ $page_html .= '<div class="tablenav bottom">' .
280
+ '<div class="alignleft actions bulkactions">' .
281
+ '<label for="bulk-action-selector-bottom" class="screen-reader-text">Select bulk action</label>' .
282
+ '<select name="action2" id="bulk-action-selector-bottom">' .
283
+ '<option value="-1">' . __( "Bulk Actions", "custom-permalinks" ) . '</option>' .
284
+ '<option value="delete">' . __( "Delete Permalinks", "custom-permalinks" ) . '</option>' .
285
+ '</select>' .
286
+ '<input type="submit" id="doaction2" class="button action" value="Apply">' .
287
+ '</div>' .
288
+ $pagination_html .
289
+ '</div>' .
290
+ '</form></div>';
291
+
292
+ echo $page_html;
293
+ }
294
+ }
admin/class-custom-permalinks-updates.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package CustomPermalinks
4
+ */
5
+
6
+ class Custom_Permalinks_Updates
7
+ {
8
+
9
+ /**
10
+ * Initializes WordPress hooks.
11
+ */
12
+ function __construct()
13
+ {
14
+ $this->update_version_details();
15
+ }
16
+
17
+ /**
18
+ * Fetch site details and sent it to CP.
19
+ *
20
+ * @since 2.0.0
21
+ * @access private
22
+ */
23
+ private function update_version_details()
24
+ {
25
+ if ( function_exists( 'curl_init' ) === true ) {
26
+ $admin_email = get_bloginfo( 'admin_email' );
27
+ $curl_url = 'https://www.custompermalinks.com/plugin-update/';
28
+ $site_name = get_bloginfo( 'name' );
29
+ $site_url = get_bloginfo( 'wpurl' );
30
+ $wp_version = get_bloginfo( 'version' );
31
+
32
+ $updates = array(
33
+ 'action' => 'install',
34
+ 'admin_email' => $admin_email,
35
+ 'plugin_version' => CUSTOM_PERMALINKS_PLUGIN_VERSION,
36
+ 'site_name' => $site_name,
37
+ 'site_url' => $site_url,
38
+ 'wp_version' => $wp_version,
39
+ );
40
+
41
+ // Create a connection
42
+ $curl_conn = curl_init( $curl_url );
43
+
44
+ // Generate URL-encoded query string
45
+ $encoded_data = http_build_query( $updates, '', '&' );
46
+
47
+ // Setting options
48
+ curl_setopt( $curl_conn, CURLOPT_POST, 1 );
49
+ curl_setopt( $curl_conn, CURLOPT_POSTFIELDS, $encoded_data );
50
+ curl_setopt( $curl_conn, CURLOPT_RETURNTRANSFER, TRUE );
51
+
52
+ // Execute the given cURL session
53
+ curl_exec( $curl_conn );
54
+
55
+ // Closes a cURL session and frees all resources
56
+ curl_close( $curl_conn );
57
+ }
58
+ }
59
+ }
admin/css/about-plugins.css DELETED
@@ -1,213 +0,0 @@
1
- .wrap {
2
- margin: 2em auto 1em;
3
- max-width: 1090px;
4
- }
5
- .wrap .float {
6
- width: calc(100% - 188px);
7
- float: left;
8
- box-sizing: border-box;
9
- }
10
- .wrap .float:nth-child(2) {
11
- width: 128px;
12
- margin: 40px 0 70px 50px;
13
- }
14
- .wrap h1 {
15
- margin: 40px auto 20px;
16
- font-size: 2.5em;
17
- }
18
- .tagline p {
19
- font-size: 1.3em;
20
- margin-bottom: 1em;
21
- margin: 0 auto 1em;
22
- }
23
- p a {
24
- text-decoration: none;
25
- }
26
- #footer-left a {
27
- text-decoration: underline;
28
- }
29
- a .star svg polygon {
30
- fill: #f9d539;
31
- }
32
- a .star svg:hover polygon {
33
- fill: #ff7c00;
34
- }
35
- .product {
36
- width: 100%;
37
- display: inline-block;
38
- text-align: center;
39
- }
40
- .product > span {
41
- font-size: 1.3em;
42
- margin-bottom: 1em;
43
- display: block;
44
- text-align: left;
45
- margin: 0 auto 1em;
46
- }
47
- .product h2 {
48
- display: block;
49
- margin: 1em auto;
50
- font-size: 2.2em;
51
- text-align:left;
52
- }
53
- .product .box {
54
- background-color: #fff;
55
- width: 300px;
56
- min-height: 200px;
57
- text-align: center;
58
- padding: 20px;
59
- box-shadow: 2px 2px 3px #d1d1d1;
60
- display: inline-block;
61
- margin: 10px;
62
- vertical-align: top;
63
- }
64
- .product .tagline{
65
- text-align: center;
66
- }
67
- .product .img {
68
- background: #eee;
69
- border-radius: 50%;
70
- width: 150px;
71
- height: 150px;
72
- margin: 0 auto;
73
- }
74
- .product .img svg,
75
- .product .img img {
76
- max-width: 70%;
77
- margin-top: 25px;
78
- }
79
- .product .h3 {
80
- margin-bottom: 5px;
81
- }
82
-
83
- .product p {
84
- color: #888;
85
- font-size: 14px;
86
- line-height: 26px;
87
- text-align: left;
88
- transition: max-height 450ms 100ms ease;
89
- margin: 1em 0 2em;
90
- }
91
- @media(min-width:746px) {
92
- .product p {
93
- min-height: 185px;
94
- max-height: 135px;
95
- overflow: hidden;
96
- }
97
- .product .box:hover p {
98
- max-height: 300px
99
- }
100
- }
101
- .box.recommended {
102
- position: relative;
103
- background: rgb(232, 235, 238);
104
- }
105
- .box.recommended * {
106
- position: relative;
107
- z-index:2;
108
- }
109
- .box.recommended:before {
110
- content: "";
111
- position: absolute;
112
- width: 100%;
113
- height: 100%;
114
- transition: all 350ms ease;
115
- z-index: 1;
116
- background: aliceblue;
117
- right: 0;
118
- top: 0;
119
- background: linear-gradient(35deg, rgb(232, 235, 238) 62%,rgba(181,198,208,1) 50%);
120
- transform-origin: top right;
121
- }
122
- @keyframes blinking {
123
- 0%,100%{opacity:0.1}
124
- 25%,75%{opacity:1}
125
- }
126
- .box.recommended:after {
127
- content: "RECOMMENDED";
128
- position: absolute;
129
- top: 41px;
130
- right: -11px;
131
- color: #fff;
132
- font-size: 18px;
133
- font-weight: bold;
134
- transform: rotateZ(35deg);
135
- font-family: sans-serif;
136
- z-index: 1;
137
- animation: blinking 2s infinite linear;
138
- }
139
- .box.recommended:hover:before {
140
- height: 175px;
141
- width: 150px;
142
- }
143
- .box.recommended:hover:after {
144
- animation: blinking 2s 1 linear;
145
- }
146
-
147
- .box > a {
148
- display: inline-block;
149
- float: right;
150
- background: rgb(181,198,208);
151
- color: #fff;
152
- background: linear-gradient(-35deg, rgba(216,225,231,0.8) 12%,rgb(181,198,208) 13%);
153
- text-decoration: none;
154
- font-size:20px;
155
- padding: 8px 17px;
156
- border-radius: 3px;
157
- transition: all 250ms ease;
158
- }
159
- .box > a:hover {
160
- font-size: 22px;
161
- }
162
- @media(max-width:991px) {
163
- .wrap {
164
- max-width: 725px;
165
- }
166
- }
167
- @media(max-width:767px) {
168
- .wrap {
169
- max-width: 640px;
170
- }
171
- .product .box {
172
- width: 258px;
173
- min-height: 410px;
174
- }
175
- }
176
- @media(max-width:650px){
177
- .wrap {
178
- max-width: 460px;
179
- }
180
- .product .box {
181
- width: 400px;
182
- max-width: 90%;
183
- min-height: inherit;
184
- margin-left: 0;
185
- margin-right: 0;
186
- box-sizing: border-box;
187
- }
188
- .wrap .float {
189
- width: 100%;
190
- }
191
- .wrap .float:nth-child(2) {
192
- margin: 40px 0 70px 50px;
193
- position: absolute;
194
- right: 20px;
195
- }
196
- .wrap h1 {
197
- margin: 70px 0 30px;
198
- width: 300px;
199
- line-height: 1.2em;
200
- }
201
- }
202
- @media(max-width:450px) {
203
- .wrap h1 {
204
- margin: 0px 0 150px;
205
- font-size: 2em;
206
- width: 300px;
207
- }
208
- .wrap .float:nth-child(2) {
209
- right: inherit;
210
- margin: 80px auto 0;
211
- text-align: center;
212
- }
213
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/css/about-plugins.min.css CHANGED
@@ -1 +1 @@
1
- .wrap{margin:2em auto 1em;max-width:1090px}.wrap .float{width:calc(100% - 188px);float:left;box-sizing:border-box}.wrap .float:nth-child(2){width:128px;margin:40px 0 70px 50px}.wrap h1{margin:40px auto 20px;font-size:2.5em}.tagline p{font-size:1.3em;margin:0 auto 1em}p a{text-decoration:none}#footer-left a{text-decoration:underline}a .star svg polygon{fill:#f9d539}a .star svg:hover polygon{fill:#ff7c00}.product{width:100%;display:inline-block;text-align:center}.product > span{font-size:1.3em;display:block;text-align:left;margin:0 auto 1em}.product h2{display:block;margin:1em auto;font-size:2.2em;text-align:left}.product .box{background-color:#fff;width:300px;min-height:200px;text-align:center;padding:20px;box-shadow:2px 2px 3px #d1d1d1;display:inline-block;margin:10px;vertical-align:top}.product .tagline{text-align:center}.product .img{background:#eee;border-radius:50%;width:150px;height:150px;margin:0 auto}.product .img svg,.product .img img{max-width:70%;margin-top:25px}.product .h3{margin-bottom:5px}.product p{color:#888;font-size:14px;line-height:26px;text-align:left;transition:max-height 450ms 100ms ease;margin:1em 0 2em}@media(min-width:746px){.product p{min-height:185px;max-height:135px;overflow:hidden}.product .box:hover p{max-height:300px}}.box.recommended{position:relative;background:#e8ebee}.box.recommended *{position:relative;z-index:2}.box.recommended:before{content:"";position:absolute;width:100%;height:100%;transition:all 350ms ease;z-index:1;background:#f0f8ff;right:0;top:0;background:linear-gradient(35deg,#e8ebee 62%,rgba(181,198,208,1) 50%);transform-origin:top right}@keyframes blinking{0%,100%{opacity:.1}25%,75%{opacity:1}}.box.recommended:after{content:"RECOMMENDED";position:absolute;top:41px;right:-11px;color:#fff;font-size:18px;font-weight:700;transform:rotateZ(35deg);font-family:sans-serif;z-index:1;animation:blinking 2s infinite linear}.box.recommended:hover:before{height:175px;width:150px}.box.recommended:hover:after{animation:blinking 2s 1 linear}.box > a{display:inline-block;float:right;background:#b5c6d0;color:#fff;background:linear-gradient(-35deg,rgba(216,225,231,0.8) 12%,#b5c6d0 13%);text-decoration:none;font-size:20px;padding:8px 17px;border-radius:3px;transition:all 250ms ease}.box > a:hover{font-size:22px}@media(max-width:991px){.wrap{max-width:725px}}@media(max-width:767px){.wrap{max-width:640px}.product .box{width:258px;min-height:410px}}@media(max-width:650px){.wrap{max-width:460px}.product .box{width:400px;max-width:90%;min-height:inherit;margin-left:0;margin-right:0;box-sizing:border-box}.wrap .float{width:100%}.wrap .float:nth-child(2){margin:40px 0 70px 50px;position:absolute;right:20px}.wrap h1{margin:70px 0 30px;width:300px;line-height:1.2em}}@media(max-width:450px){.wrap h1{margin:0 0 150px;font-size:2em;width:300px}.wrap .float:nth-child(2){right:inherit;margin:80px auto 0;text-align:center}}
1
+ .wrap{margin:2em auto 1em;max-width:1090px}.wrap .float{width:calc(100% - 188px);float:left;box-sizing:border-box}.wrap .float:nth-child(2){width:128px;margin:40px 0 70px 50px}.wrap h1{margin:40px auto 20px;font-size:2.5em}.tagline p{font-size:1.3em;margin:0 auto 1em}p a{text-decoration:none}.box>a{display:inline-block;float:right;color:#fff;background:linear-gradient(-35deg,rgba(216,225,231,.8) 12%,#b5c6d0 13%);text-decoration:none;font-size:20px;padding:8px 17px;border-radius:3px;transition:all 250ms ease}.box>a:hover{font-size:22px}#footer-left a{text-decoration:underline}a .star svg polygon{fill:#f9d539}a .star svg:hover polygon{fill:#ff7c00}.product{width:100%;display:inline-block;text-align:center}.product>span{font-size:1.3em;display:block;text-align:left;margin:0 auto 1em}.product h2{display:block;margin:1em auto;font-size:2.2em;text-align:left}.product .box{background-color:#fff;width:300px;min-height:200px;text-align:center;padding:20px;box-shadow:2px 2px 3px #d1d1d1;display:inline-block;margin:10px;vertical-align:top}.product .tagline{text-align:center}.product .img{background:#eee;border-radius:50%;width:150px;height:150px;margin:0 auto}.product .img img,.product .img svg{max-width:70%;margin-top:25px}.product .h3{margin-bottom:5px}.product p{color:#888;font-size:14px;line-height:26px;text-align:left;transition:max-height 450ms .1s ease;margin:1em 0 2em}@media (min-width:746px){.product p{min-height:185px;max-height:135px;overflow:hidden}.product .box:hover p{max-height:300px}}.box.recommended{position:relative;background:#e8ebee}.box.recommended *{position:relative;z-index:2}.box.recommended::before{content:"";position:absolute;width:100%;height:100%;transition:all 350ms ease;z-index:1;right:0;top:0;background:linear-gradient(35deg,#e8ebee 62%,rgba(181,198,208,1) 50%);transform-origin:top right}@keyframes blinking{0%,100%{opacity:.1}25%,75%{opacity:1}}.box.recommended::after{content:"RECOMMENDED";position:absolute;top:41px;right:-11px;color:#fff;font-size:18px;font-weight:700;transform:rotateZ(35deg);font-family:sans-serif;z-index:1;animation:blinking 2s infinite linear}.box.recommended:hover::before{height:175px;width:150px}.box.recommended:hover::after{animation:blinking 2s 1 linear}@media (max-width:991px){.wrap{max-width:725px}}@media (max-width:767px){.wrap{max-width:640px}.product .box{width:258px;min-height:410px}}@media (max-width:650px){.wrap{max-width:460px}.product .box{width:400px;max-width:90%;min-height:inherit;margin-left:0;margin-right:0;box-sizing:border-box}.wrap .float{width:100%}.wrap .float:nth-child(2){margin:40px 0 70px 50px;position:absolute;right:20px}.wrap h1{margin:70px 0 30px;width:300px;line-height:1.2em}}@media (max-width:450px){.wrap h1{margin:0 0 150px;font-size:2em;width:300px}.wrap .float:nth-child(2){right:inherit;margin:80px auto 0;text-align:center}}
changelog.txt CHANGED
@@ -1,3 +1,4 @@
 
1
  == Changelog ==
2
 
3
  This file contains only old changelog. See readme.txt for newer versions.
@@ -261,7 +262,7 @@ This file contains only old changelog. See readme.txt for newer versions.
261
 
262
  = 0.7.9 =
263
 
264
- * Support for custom post types, by Balzs N�meth
265
 
266
  = 0.7.8 =
267
 
1
+
2
  == Changelog ==
3
 
4
  This file contains only old changelog. See readme.txt for newer versions.
262
 
263
  = 0.7.9 =
264
 
265
+ * Support for custom post types, by Bal·zs NÈmeth
266
 
267
  = 0.7.8 =
268
 
custom-permalinks.php CHANGED
@@ -3,10 +3,9 @@
3
  * Plugin Name: Custom Permalinks
4
  * Plugin URI: https://wordpress.org/plugins/custom-permalinks/
5
  * Description: Set custom permalinks on a per-post basis
6
- * Version: 1.5.1
7
  * Author: Sami Ahmed Siddiqui
8
  * Author URI: https://www.custompermalinks.com/
9
- * Donate link: https://www.paypal.me/yasglobal
10
  * License: GPLv3
11
  *
12
  * Text Domain: custom-permalinks
@@ -17,7 +16,7 @@
17
 
18
  /**
19
  * Custom Permalinks - Update Permalinks of Post/Pages and Categories
20
- * Copyright 2008-2019 Sami Ahmed Siddiqui <sami.siddiqui@yasglobal.com>
21
  *
22
  * This program is free software: you can redistribute it and/or modify
23
  * it under the terms of the GNU General Public License as published by
@@ -35,121 +34,154 @@
35
 
36
  // Make sure we don't expose any info if called directly
37
  if ( ! defined( 'ABSPATH' ) ) {
38
- echo 'Hi there! I\'m just a plugin, not much I can do when called directly.';
39
- exit;
40
  }
41
 
42
- class Custom_Permalinks {
43
-
44
- /**
45
- * Class constructor.
46
- */
47
- public function __construct() {
48
- $this->setup_constants();
49
- $this->includes();
50
-
51
- add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
52
- }
53
-
54
- /**
55
- * Setup plugin constants
56
- *
57
- * @access private
58
- * @since 1.2.18
59
- * @return void
60
- */
61
- private function setup_constants() {
62
- if ( ! defined( 'CUSTOM_PERMALINKS_FILE' ) ) {
63
- define( 'CUSTOM_PERMALINKS_FILE', __FILE__ );
64
- }
65
 
66
- if ( ! defined( 'CUSTOM_PERMALINKS_PLUGIN_VERSION' ) ) {
67
- define( 'CUSTOM_PERMALINKS_PLUGIN_VERSION', '1.5.1' );
68
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
- if ( ! defined( 'CUSTOM_PERMALINKS_PATH' ) ) {
71
- define( 'CUSTOM_PERMALINKS_PATH', plugin_dir_path( CUSTOM_PERMALINKS_FILE ) );
 
 
 
 
 
72
  }
73
 
74
- if ( ! defined( 'CUSTOM_PERMALINKS_BASENAME' ) ) {
75
- define( 'CUSTOM_PERMALINKS_BASENAME', plugin_basename( CUSTOM_PERMALINKS_FILE ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  }
77
- }
78
-
79
- /**
80
- * Include required files
81
- *
82
- * @access private
83
- * @since 1.2.18
84
- *
85
- * @return void
86
- */
87
- private function includes() {
88
- require_once(
89
- CUSTOM_PERMALINKS_PATH . 'frontend/class-custom-permalinks-frontend.php'
90
- );
91
- $cp_frontend = new Custom_Permalinks_Frontend();
92
- $cp_frontend->init();
93
-
94
- require_once(
95
- CUSTOM_PERMALINKS_PATH . 'frontend/class-custom-permalinks-form.php'
96
- );
97
- $cp_form = new Custom_Permalinks_Form();
98
- $cp_form->init();
99
-
100
- if ( is_admin() ) {
101
- require_once(
102
- CUSTOM_PERMALINKS_PATH . 'admin/class-custom-permalinks-admin.php'
103
- );
104
- new Custom_Permalinks_Admin();
105
-
106
- register_activation_hook( CUSTOM_PERMALINKS_FILE, array( 'Custom_Permalinks', 'plugin_activate' ) );
 
 
 
 
 
 
 
 
107
  }
108
- }
109
-
110
- /**
111
- * Loads the plugin language files
112
- *
113
- * @access public
114
- * @since 1.2.22
115
- *
116
- * @return void
117
- */
118
- public static function plugin_activate() {
119
- $role = get_role( 'administrator' );
120
- if ( ! empty( $role ) ) {
121
- $role->add_cap( 'cp_view_post_permalinks' );
122
- $role->add_cap( 'cp_view_category_permalinks' );
123
  }
124
 
125
- add_role(
126
- 'custom_permalinks_manager',
127
- __( 'Custom Permalinks Manager' ),
128
- array(
129
- 'cp_view_post_permalinks' => true,
130
- 'cp_view_category_permalinks' => true
131
- )
132
- );
133
- }
134
-
135
- /**
136
- * Loads the plugin language files
137
- *
138
- * @access public
139
- * @since 1.2.18
140
- *
141
- * @return void
142
- */
143
- public function load_textdomain() {
144
- $current_version = get_option( 'custom_permalinks_plugin_version', -1 );
145
- if ( -1 === $current_version || CUSTOM_PERMALINKS_PLUGIN_VERSION < $current_version ) {
146
- Custom_Permalinks::plugin_activate();
147
- update_option( 'custom_permalinks_plugin_version', CUSTOM_PERMALINKS_PLUGIN_VERSION );
 
 
 
 
 
 
 
148
  }
149
- load_plugin_textdomain( 'custom-permalinks', FALSE,
150
- basename( dirname( CUSTOM_PERMALINKS_FILE ) ) . '/languages/'
151
- );
152
- }
153
  }
154
 
155
  new Custom_Permalinks();
3
  * Plugin Name: Custom Permalinks
4
  * Plugin URI: https://wordpress.org/plugins/custom-permalinks/
5
  * Description: Set custom permalinks on a per-post basis
6
+ * Version: 1.6.0
7
  * Author: Sami Ahmed Siddiqui
8
  * Author URI: https://www.custompermalinks.com/
 
9
  * License: GPLv3
10
  *
11
  * Text Domain: custom-permalinks
16
 
17
  /**
18
  * Custom Permalinks - Update Permalinks of Post/Pages and Categories
19
+ * Copyright 2008-2020 Sami Ahmed Siddiqui <sami.siddiqui@yasglobal.com>
20
  *
21
  * This program is free software: you can redistribute it and/or modify
22
  * it under the terms of the GNU General Public License as published by
34
 
35
  // Make sure we don't expose any info if called directly
36
  if ( ! defined( 'ABSPATH' ) ) {
37
+ echo 'Hi there! I\'m just a plugin, not much I can do when called directly.';
38
+ exit;
39
  }
40
 
41
+ class Custom_Permalinks
42
+ {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
+ /**
45
+ * Class constructor.
46
+ */
47
+ public function __construct()
48
+ {
49
+ if ( ! defined( 'CUSTOM_PERMALINKS_FILE' ) ) {
50
+ define( 'CUSTOM_PERMALINKS_FILE', __FILE__ );
51
+ }
52
+
53
+ if ( ! defined( 'CUSTOM_PERMALINKS_PLUGIN_VERSION' ) ) {
54
+ define( 'CUSTOM_PERMALINKS_PLUGIN_VERSION', '1.6.0' );
55
+ }
56
+
57
+ if ( ! defined( 'CUSTOM_PERMALINKS_PATH' ) ) {
58
+ define( 'CUSTOM_PERMALINKS_PATH', plugin_dir_path( __FILE__ ) );
59
+ }
60
 
61
+ if ( ! defined( 'CUSTOM_PERMALINKS_BASENAME' ) ) {
62
+ define( 'CUSTOM_PERMALINKS_BASENAME', plugin_basename( __FILE__ ) );
63
+ }
64
+
65
+ $this->includes();
66
+
67
+ add_action( 'plugins_loaded', array( $this, 'check_loaded_plugins' ) );
68
  }
69
 
70
+ /**
71
+ * Include required files.
72
+ *
73
+ * @since 1.2.18
74
+ * @access private
75
+ */
76
+ private function includes()
77
+ {
78
+ $cp_files_path = array(
79
+ 'admin' => CUSTOM_PERMALINKS_PATH . 'admin/class-custom-permalinks-admin.php',
80
+ 'form' => CUSTOM_PERMALINKS_PATH . 'frontend/class-custom-permalinks-form.php',
81
+ 'frontend' => CUSTOM_PERMALINKS_PATH . 'frontend/class-custom-permalinks-frontend.php',
82
+ );
83
+
84
+ require_once $cp_files_path['frontend'];
85
+ require_once $cp_files_path['form'];
86
+
87
+ $cp_frontend = new Custom_Permalinks_Frontend();
88
+ $cp_frontend->init();
89
+
90
+ $cp_form = new Custom_Permalinks_Form();
91
+ $cp_form->init();
92
+
93
+ if ( is_admin() ) {
94
+ include_once $cp_files_path['admin'];
95
+ new Custom_Permalinks_Admin();
96
+
97
+ register_activation_hook( CUSTOM_PERMALINKS_FILE,
98
+ array( 'Custom_Permalinks', 'add_role_and_update_details' )
99
+ );
100
+ }
101
  }
102
+
103
+ /**
104
+ * Add role for the view post and category permalinks and by default assign
105
+ * it to the administrator if administrator role exist. Also, update details
106
+ * when plugin gets updated.
107
+ *
108
+ * @since 1.2.22
109
+ * @access public
110
+ */
111
+ public static function add_role_and_update_details()
112
+ {
113
+ $admin_role = get_role( 'administrator' );
114
+ $cp_role = get_role( 'custom_permalinks_manager' );
115
+ $current_version = get_option( 'custom_permalinks_plugin_version', -1 );
116
+
117
+ if ( ! empty( $admin_role ) ) {
118
+ $admin_role->add_cap( 'cp_view_post_permalinks' );
119
+ $admin_role->add_cap( 'cp_view_category_permalinks' );
120
+ }
121
+
122
+ if ( empty( $cp_role ) ) {
123
+ add_role( 'custom_permalinks_manager', __( 'Custom Permalinks Manager' ),
124
+ array(
125
+ 'cp_view_post_permalinks' => true,
126
+ 'cp_view_category_permalinks' => true
127
+ )
128
+ );
129
+ }
130
+
131
+ if ( -1 === $current_version
132
+ || $current_version < CUSTOM_PERMALINKS_PLUGIN_VERSION
133
+ ) {
134
+ Custom_Permalinks::update_details();
135
+
136
+ update_option( 'custom_permalinks_plugin_version',
137
+ CUSTOM_PERMALINKS_PLUGIN_VERSION
138
+ );
139
+ }
140
  }
141
+
142
+ /**
143
+ * Loads the plugin language files.
144
+ *
145
+ * @since 1.2.18
146
+ * @access public
147
+ */
148
+ public function update_details()
149
+ {
150
+ require_once CUSTOM_PERMALINKS_PATH . 'admin/class-custom-permalinks-updates.php';
151
+ new Custom_Permalinks_Updates();
 
 
 
 
152
  }
153
 
154
+ /**
155
+ * Check if role not exist then call the function to add it. Update site
156
+ * details if plugin gets updated. Also, loads the plugin language files to
157
+ * support different languages.
158
+ *
159
+ * @since 1.2.18
160
+ * @access public
161
+ */
162
+ public function check_loaded_plugins()
163
+ {
164
+ if ( is_admin() ) {
165
+ $cp_role = get_role( 'custom_permalinks_manager' );
166
+ $current_version = get_option( 'custom_permalinks_plugin_version', -1 );
167
+
168
+ if ( empty( $cp_role ) ) {
169
+ Custom_Permalinks::add_role_and_update_details();
170
+ } elseif ( -1 === $current_version
171
+ || $current_version < CUSTOM_PERMALINKS_PLUGIN_VERSION
172
+ ) {
173
+ Custom_Permalinks::update_details();
174
+
175
+ update_option( 'custom_permalinks_plugin_version',
176
+ CUSTOM_PERMALINKS_PLUGIN_VERSION
177
+ );
178
+ }
179
+ }
180
+
181
+ load_plugin_textdomain( 'custom-permalinks', FALSE,
182
+ basename( dirname( CUSTOM_PERMALINKS_FILE ) ) . '/languages/'
183
+ );
184
  }
 
 
 
 
185
  }
186
 
187
  new Custom_Permalinks();
frontend/class-custom-permalinks-form.php CHANGED
@@ -1,540 +1,677 @@
1
  <?php
2
  /**
3
- * @package CustomPermalinks\Frontend\Form
4
  */
5
 
6
- class Custom_Permalinks_Form {
7
-
8
- private $permalink_metabox = 0;
9
-
10
- /**
11
- * Initialize WordPress Hooks
12
- *
13
- * @access public
14
- * @since 1.2
15
- * @updated 1.5.0
16
- *
17
- * @return void
18
- */
19
- public function init() {
20
-
21
- add_filter( 'get_sample_permalink_html',
22
- array( $this, 'custom_permalinks_get_sample_permalink_html' ), 10, 4
23
- );
24
-
25
- add_action( 'add_meta_boxes',
26
- array( $this, 'permalink_edit_box' )
27
- );
28
-
29
- add_filter( 'is_protected_meta',
30
- array( $this, 'make_meta_protected' ), 10, 3
31
- );
32
-
33
- add_action( 'save_post',
34
- array( $this, 'custom_permalinks_save_post' ), 10, 3
35
- );
36
- add_action( 'delete_post',
37
- array( $this, 'custom_permalinks_delete_permalink' ), 10
38
- );
39
-
40
- add_action( 'category_add_form',
41
- array( $this, 'custom_permalinks_term_options' )
42
- );
43
- add_action( 'category_edit_form',
44
- array( $this, 'custom_permalinks_term_options' )
45
- );
46
- add_action( 'post_tag_add_form',
47
- array( $this, 'custom_permalinks_term_options' )
48
- );
49
- add_action( 'post_tag_edit_form',
50
- array( $this, 'custom_permalinks_term_options' )
51
- );
52
-
53
- add_action( 'edited_post_tag',
54
- array( $this, 'custom_permalinks_save_tag' )
55
- );
56
- add_action( 'edited_category',
57
- array( $this, 'custom_permalinks_save_category' )
58
- );
59
- add_action( 'create_post_tag',
60
- array( $this, 'custom_permalinks_save_tag' )
61
- );
62
- add_action( 'create_category',
63
- array( $this, 'custom_permalinks_save_category' )
64
- );
65
- add_action( 'delete_post_tag',
66
- array( $this, 'custom_permalinks_delete_term' )
67
- );
68
- add_action( 'delete_post_category',
69
- array( $this, 'custom_permalinks_delete_term' )
70
- );
71
- }
72
-
73
- /**
74
- * Register meta box(es).
75
- *
76
- * @access public
77
- * @since 1.4.0
78
- *
79
- * @return void
80
- */
81
- public function permalink_edit_box() {
82
- add_meta_box( 'custom-permalinks-edit-box',
83
- __( 'Permalink', 'custom-permalinks' ),
84
- array( $this, 'meta_edit_form' ), null, 'normal', 'high',
85
- array(
86
- '__back_compat_meta_box' => false,
87
- )
88
- );
89
- }
90
-
91
- /**
92
- * Set the meta_keys to protected which is created by the plugin.
93
- *
94
- * @access public
95
- * @since 1.4.0
96
- *
97
- * @param boolean $protected
98
- * Whether the key is protected or not
99
- * @param string $meta_key
100
- * Meta key
101
- * @param string $meta_type
102
- * Meta type
103
- *
104
- * @return boolean
105
- * return `true` for the custom_permalink key
106
- */
107
- public function make_meta_protected( $protected, $meta_key, $meta_type ) {
108
- if ( 'custom_permalink' === $meta_key ) {
109
- $protected = true;
110
  }
111
- return $protected;
112
- }
113
-
114
- /**
115
- * Save per-post options
116
- *
117
- * @access public
118
- * @return void
119
- */
120
- public function custom_permalinks_save_post( $id ) {
121
- if ( ! isset( $_REQUEST['custom_permalinks_edit'] ) ) {
122
- return;
123
- }
124
-
125
- delete_post_meta( $id, 'custom_permalink' );
126
 
127
- $cp_frontend = new Custom_Permalinks_Frontend();
128
- $original_link = $cp_frontend->custom_permalinks_original_post_link( $id );
129
- $permalink_structure = get_option( 'permalink_structure' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
- if ( $_REQUEST['custom_permalink'] && $_REQUEST['custom_permalink'] != $original_link ) {
132
- add_post_meta( $id, 'custom_permalink',
133
- str_replace( '%2F', '/',
134
- urlencode( ltrim( stripcslashes( $_REQUEST['custom_permalink'] ), "/" ) )
135
- )
136
- );
137
- }
138
- }
139
-
140
- /**
141
- * Delete Post Permalink
142
- *
143
- * @access public
144
- * @return void
145
- */
146
- public function custom_permalinks_delete_permalink( $id ) {
147
- global $wpdb;
148
- $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE meta_key = 'custom_permalink' AND post_id = %d", $id ) );
149
- }
150
-
151
- /**
152
- * Per-post/page options (Wordpress > 2.9)
153
- *
154
- * @access public
155
- * @return string
156
- */
157
- public function custom_permalinks_get_sample_permalink_html( $html, $id, $new_title, $new_slug ) {
158
- $post = get_post( $id );
159
- $this->permalink_metabox = 1;
160
-
161
- if ( 'attachment' == $post->post_type || $post->ID == get_option( 'page_on_front' ) ) {
162
- return $html;
163
  }
164
 
165
- $exclude_post_types = $post->post_type;
166
- $excluded = apply_filters( 'custom_permalinks_exclude_post_type', $exclude_post_types );
167
- if ( '__true' === $excluded ) {
168
- return $html;
 
 
 
 
 
 
 
 
 
 
 
169
  }
170
- $permalink = get_post_meta( $id, 'custom_permalink', true );
171
 
172
- ob_start();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
 
174
- $cp_frontend = new Custom_Permalinks_Frontend();
175
- if ( 'page' == $post->post_type ) {
176
- $original_permalink = $cp_frontend->custom_permalinks_original_page_link( $id );
177
- $view_post = __( 'View Page', 'custom-permalinks' );
178
- } else {
179
- $original_permalink = $cp_frontend->custom_permalinks_original_post_link( $id );
180
- $view_post = __( 'View ' . ucfirst( $post->post_type ), 'custom-permalinks' );
181
- }
182
- $this->custom_permalinks_get_form( $permalink, $original_permalink, false, $post->post_name );
183
-
184
- $content = ob_get_contents();
185
- ob_end_clean();
186
-
187
- $view_post_link = get_permalink( $post );
188
-
189
- return '<strong>' . __( 'Permalink:', 'custom-permalinks' ) . "</strong>\n" . $content .
190
- ( isset( $view_post ) ? "<span id='view-post-btn'><a href='$view_post_link' class='button button-small' target='_blank'>$view_post</a></span>\n" : "" );
191
- }
192
-
193
- /**
194
- * Per-post/page options (Wordpress >= 5.0)
195
- * WHERE Gutenberg Editor is running
196
- *
197
- * @access public
198
- * @return string
199
- */
200
- public function meta_edit_form( $post ) {
201
- if ( isset( $this->permalink_metabox ) && 1 === $this->permalink_metabox ) {
202
- wp_enqueue_script( 'custom-permalinks-form',
203
- plugins_url( '/js/script-form.min.js', __FILE__ ), array(), false, true
204
- );
205
- return;
206
  }
207
 
208
- $screen = get_current_screen();
209
- if ( 'add' === $screen->action ) {
210
- wp_enqueue_script( 'custom-permalinks-form',
211
- plugins_url( '/js/script-form.min.js', __FILE__ ), array(), false, true
212
- );
213
- return;
214
- }
 
 
 
 
 
215
 
216
- if ( 'attachment' == $post->post_type || $post->ID == get_option( 'page_on_front' ) ) {
217
- return;
 
 
 
 
 
 
 
 
 
 
 
218
  }
219
 
220
- $exclude_post_types = $post->post_type;
221
- $excluded = apply_filters( 'custom_permalinks_exclude_post_type', $exclude_post_types );
222
- if ( '__true' === $excluded ) {
223
- wp_enqueue_script( 'custom-permalinks-form',
224
- plugins_url( '/js/script-form.min.js', __FILE__ ), array(), false, true
225
- );
226
- return;
 
 
 
227
  }
228
- $permalink = get_post_meta( $post->ID, 'custom_permalink', true );
229
 
230
- ob_start();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
 
232
- $cp_frontend = new Custom_Permalinks_Frontend();
233
- if ( 'page' == $post->post_type ) {
234
- $original_permalink = $cp_frontend->custom_permalinks_original_page_link( $post->ID );
235
- $view_post = __( 'View Page', 'custom-permalinks' );
236
- } else {
237
- $original_permalink = $cp_frontend->custom_permalinks_original_post_link( $post->ID );
238
- $view_post = __( 'View ' . ucfirst( $post->post_type ), 'custom-permalinks' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  }
240
- $this->custom_permalinks_get_form( $permalink, $original_permalink, false, $post->post_name );
241
 
242
- $content = ob_get_contents();
243
- ob_end_clean();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
 
245
- if ( 'trash' != $post->post_status ) {
246
- wp_enqueue_script( 'custom-permalinks-form',
247
- plugins_url( '/js/script-form.min.js', __FILE__ ), array(), false, true
248
- );
249
- $view_post_link = get_permalink( $post );
250
 
251
- $content .= ' <span id="view-post-btn">' .
252
- '<a href="' . $view_post_link . '" class="button button-small" target="_blank">' . $view_post . '</a>' .
253
- '</span><br>';
254
  }
255
- echo $content;
256
- }
257
-
258
- /**
259
- * Per-post options (Wordpress < 2.9)
260
- *
261
- * @access public
262
- * @return void
263
- */
264
- public function custom_permalinks_post_options() {
265
- global $post;
266
- $post_id = $post;
267
- if ( is_object( $post_id ) ) {
268
- $post_id = $post_id->ID;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  }
270
 
271
- $permalink = get_post_meta( $post_id, 'custom_permalink', true );
272
- ?>
273
- <div class="postbox closed">
274
- <h3><?php _e( 'Custom Permalink', 'custom-permalinks' ) ?></h3>
275
- <div class="inside">
276
- <?php
277
- $cp_frontend = new Custom_Permalinks_Frontend();
278
- $cp_frontend->custom_permalinks_get_form( $permalink, $cp_frontend->custom_permalinks_original_post_link( $post_id ) );
 
 
 
 
 
 
 
 
279
  ?>
280
- </div>
281
- </div>
282
- <?php
283
- }
284
-
285
- /**
286
- * Per-page options (Wordpress < 2.9)
287
- *
288
- * @access public
289
- * @return void
290
- */
291
- public function custom_permalinks_page_options() {
292
- global $post;
293
- $post_id = $post;
294
- if (is_object( $post_id ) ) {
295
- $post_id = $post_id->ID;
 
296
  }
297
 
298
- $permalink = get_post_meta( $post_id, 'custom_permalink', true );
299
- ?>
300
- <div class="postbox closed">
301
- <h3><?php _e( 'Custom Permalink', 'custom-permalinks' ); ?></h3>
302
- <div class="inside">
303
- <?php
304
- $cp_frontend = new Custom_Permalinks_Frontend();
305
- $page_permalink = $cp_frontend->custom_permalinks_original_page_link( $post_id );
306
- $this->custom_permalinks_get_form( $permalink, $page_permalink );
307
- ?>
308
- </div>
309
- </div>
310
- <?php
311
- }
312
-
313
- /**
314
- * Per-category/tag options
315
- *
316
- * @access public
317
- * @return void
318
- */
319
- public function custom_permalinks_term_options( $object ) {
320
- if ( is_object( $object ) && isset( $object->term_id ) ) {
321
- $cp_frontend = new Custom_Permalinks_Frontend();
322
- $permalink = $cp_frontend->custom_permalinks_permalink_for_term( $object->term_id );
323
-
324
- if ( $object->term_id ) {
325
- if ( $object->taxonomy == 'post_tag' ) {
326
- $originalPermalink = $cp_frontend->custom_permalinks_original_tag_link( $object->term_id );
327
  } else {
328
- $originalPermalink = $cp_frontend->custom_permalinks_original_category_link( $object->term_id );
329
  }
330
- }
331
 
332
- $this->custom_permalinks_get_form( $permalink, $originalPermalink );
333
- } else {
334
- $this->custom_permalinks_get_form( '' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
  }
336
 
337
- // Move the save button to above this form
338
- wp_enqueue_script( 'jquery' );
339
- ?>
340
- <script type="text/javascript">
341
- jQuery(document).ready(function() {
342
- var button = jQuery('#custom_permalink_form').parent().find('.submit');
343
- button.remove().insertAfter(jQuery('#custom_permalink_form'));
344
- });
345
- </script>
346
- <?php
347
- }
348
-
349
- /**
350
- * Helper function to render form
351
- *
352
- * @access private
353
- * @return void
354
- */
355
- private function custom_permalinks_get_form( $permalink, $original = '', $renderContainers = true, $postname = '' ) {
356
- ?>
357
- <input value="true" type="hidden" name="custom_permalinks_edit" />
358
- <input value="<?php echo home_url(); ?>" type="hidden" name="custom_permalinks_home_url" id="custom_permalinks_home_url" />
359
- <input value="<?php echo htmlspecialchars( urldecode( $permalink ) ); ?>" type="hidden" name="custom_permalink" id="custom_permalink" />
360
-
361
- <?php
362
- if ( $renderContainers ) :
363
- ?>
364
- <table class="form-table" id="custom_permalink_form">
365
- <tr>
366
- <th scope="row"><?php _e( 'Custom Permalink', 'custom-permalinks' ); ?></th>
367
- <td>
368
- <?php
369
- endif;
370
- if ( $permalink == '' ) {
371
- $original = $this->custom_permalinks_check_conflicts( $original );
372
- }
373
- $post_slug = htmlspecialchars( $permalink ? urldecode( $permalink ) : urldecode( $original ) );
374
- $original_encoded_url = htmlspecialchars( urldecode( $original ) );
375
- wp_enqueue_script( 'custom-permalinks-form', plugins_url( '/js/script-form.min.js', __FILE__ ), array(), false, true );
376
- $postname_html = '';
377
- if ( isset( $postname ) && $postname != '' ) {
378
- $postname_html = '<input type="hidden" id="new-post-slug" class="text" value="' . $postname . '" />';
379
- }
380
 
381
- echo home_url() . '/<span id="editable-post-name" title="Click to edit this part of the permalink">' . $postname_html;
382
-
383
- ?>
384
- <input type="text" id="custom-permalinks-post-slug" class="text" value="<?php echo $post_slug; ?>"
385
- style="width: 250px; <?php if ( !$permalink ) echo 'color: #ddd'; ?>"
386
- onfocus="if ( this.style.color = '#ddd' ) { this.style.color = '#000'; }"
387
- onblur="document.getElementById('custom_permalink').value = this.value; if ( this.value == '' || this.value == '<?php echo $original_encoded_url; ?>' ) { this.value = '<?php echo $original_encoded_url; ?>'; this.style.color = '#ddd'; }" />
388
- </span>
389
-
390
- <?php if ( $renderContainers ) : ?>
391
- <br />
392
- <small><?php _e( 'Leave blank to disable', 'custom-permalinks' ); ?></small>
393
- </td>
394
- </tr>
395
- </table>
396
- <?php
397
- endif;
398
- }
399
-
400
- /**
401
- * Save per-tag options
402
- *
403
- * @access public
404
- * @return void
405
- */
406
- public function custom_permalinks_save_tag( $id ) {
407
- if ( ! isset( $_REQUEST['custom_permalinks_edit'] )
408
- || isset( $_REQUEST['post_ID'] ) ) {
409
- return;
410
- }
411
- $new_permalink = ltrim( stripcslashes( $_REQUEST['custom_permalink'] ), '/' );
412
 
413
- $cp_frontend = new Custom_Permalinks_Frontend();
414
- if ( $new_permalink == $cp_frontend->custom_permalinks_original_tag_link( $id ) ) {
415
- return;
 
 
 
 
 
 
 
416
  }
417
 
418
- $term = get_term( $id, 'post_tag' );
419
- $this->custom_permalinks_save_term( $term, str_replace( '%2F', '/', urlencode( $new_permalink ) ) );
420
- }
421
-
422
- /**
423
- * Save per-category options
424
- *
425
- * @access public
426
- * @return void
427
- */
428
- public function custom_permalinks_save_category( $id ) {
429
- if ( ! isset( $_REQUEST['custom_permalinks_edit'] )
430
- || isset( $_REQUEST['post_ID'] ) ) {
431
- return;
432
- }
433
- $new_permalink = ltrim( stripcslashes( $_REQUEST['custom_permalink'] ), '/' );
 
 
 
 
 
 
 
 
 
 
 
 
 
434
 
435
- $cp_frontend = new Custom_Permalinks_Frontend();
436
- if ( $new_permalink == $cp_frontend->custom_permalinks_original_category_link( $id ) ) {
437
- return;
438
- }
 
 
 
439
 
440
- $term = get_term( $id, 'category' );
441
- $this->custom_permalinks_save_term(
442
- $term, str_replace( '%2F', '/', urlencode( $new_permalink ) )
443
- );
444
- }
445
-
446
- /**
447
- * Save term (common to tags and categories)
448
- *
449
- * @access public
450
- * @return void
451
- */
452
- public function custom_permalinks_save_term( $term, $permalink ) {
453
-
454
- $this->custom_permalinks_delete_term( $term->term_id );
455
- $table = get_option( 'custom_permalink_table' );
456
- if ( $permalink ) {
457
- $table[$permalink] = array(
458
- 'id' => $term->term_id,
459
- 'kind' => ( $term->taxonomy == 'category' ? 'category' : 'tag' ),
460
- 'slug' => $term->slug
461
- );
 
 
 
 
 
462
  }
463
 
464
- update_option( 'custom_permalink_table', $table );
465
- }
466
-
467
- /**
468
- * Delete term
469
- *
470
- * @access public
471
- * @return void
472
- */
473
- public function custom_permalinks_delete_term( $id ) {
474
- $table = get_option( 'custom_permalink_table' );
475
- if ( $table ) {
476
- foreach ( $table as $link => $info ) {
477
- if ( $info['id'] == $id ) {
478
- unset( $table[$link] );
479
- break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
480
  }
481
- }
482
  }
483
- update_option( 'custom_permalink_table', $table );
484
- }
485
-
486
- /**
487
- * Check Conflicts and resolve it (e.g: Polylang)
488
- * UPDATED for Polylang hide_default setting
489
- *
490
- * @access public
491
- * @since 1.2
492
- * @updated 1.5.1
493
- *
494
- * @return string
495
- */
496
- public function custom_permalinks_check_conflicts( $requested_url = '' ) {
497
- if ( '' == $requested_url ) {
498
- return;
 
 
 
 
 
499
  }
500
 
501
- // Check if the Polylang Plugin is installed so, make changes in the URL
502
- if ( defined( 'POLYLANG_VERSION' ) ) {
503
- $polylang_config = get_option( 'polylang' );
504
- if ( $polylang_config['force_lang'] == 1 ) {
 
 
 
 
 
 
 
 
 
 
505
 
506
- if ( false !== strpos( $requested_url, 'language/' ) ) {
507
- $requested_url = str_replace( 'language/', '', $requested_url );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
508
  }
509
 
510
- /**
511
- * Check if hide_default is true and the current language is not the default.
512
- * If true the remove the lang code from the url.
513
- */
514
- if ( 1 == $polylang_config['hide_default'] ) {
515
- $current_language = '';
516
- if ( function_exists( 'pll_current_language' ) ) {
517
- // get current language
518
- $current_language = pll_current_language();
519
- }
520
-
521
- // get defualt language
522
- $default_language = $polylang_config['default_lang'];
523
-
524
- if ( $current_language !== $default_language ) {
525
- $remove_lang = ltrim( strstr( $requested_url, '/' ), '/' );
526
- if ( '' != $remove_lang ) {
527
- return $remove_lang;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
528
  }
529
- }
530
- } else {
531
- $remove_lang = ltrim( strstr( $requested_url, '/' ), '/' );
532
- if ( '' != $remove_lang ) {
533
- return $remove_lang;
534
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
535
  }
536
- }
537
  }
538
- return $requested_url;
539
- }
540
  }
1
  <?php
2
  /**
3
+ * @package CustomPermalinks
4
  */
5
 
6
+ class Custom_Permalinks_Form
7
+ {
8
+
9
+ /*
10
+ * Decide whether to show metabox or override WordPress default Permalink box.
11
+ */
12
+ private $permalink_metabox = 0;
13
+
14
+ /**
15
+ * Initialize WordPress Hooks.
16
+ *
17
+ * @since 1.2.0
18
+ * @access public
19
+ */
20
+ public function init()
21
+ {
22
+ add_action( 'add_meta_boxes', array( $this, 'permalink_edit_box' ) );
23
+ add_action( 'save_post', array( $this, 'save_post' ), 10, 3 );
24
+ add_action( 'delete_post', array( $this, 'delete_permalink' ), 10 );
25
+ add_action( 'category_add_form', array( $this, 'term_options' ) );
26
+ add_action( 'category_edit_form', array( $this, 'term_options' ) );
27
+ add_action( 'post_tag_add_form', array( $this, 'term_options' ) );
28
+ add_action( 'post_tag_edit_form', array( $this, 'term_options' ) );
29
+ add_action( 'created_term', array( $this, 'save_term' ), 10, 3 );
30
+ add_action( 'edited_term', array( $this, 'save_term' ), 10, 3 );
31
+ add_action( 'delete_term', array( $this, 'delete_term_permalink' ), 10, 3 );
32
+ add_action( 'rest_api_init', array( $this, 'rest_edit_form' ) );
33
+ add_action( 'update_option_page_on_front',
34
+ array( $this, 'static_homepage' ), 10, 2
35
+ );
36
+
37
+ add_filter( 'get_sample_permalink_html',
38
+ array( $this, 'sample_permalink_html' ), 10, 2
39
+ );
40
+ add_filter( 'is_protected_meta', array( $this, 'protect_meta' ), 10, 2 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
+ /**
44
+ * Initialize WordPress Hooks.
45
+ *
46
+ * @since 1.6.0
47
+ * @access private
48
+ *
49
+ * @param object $post WP Post Object.
50
+ *
51
+ * return bool false Whether to show Custom Permalink form or not.
52
+ */
53
+ private function exclude_custom_permalinks( $post )
54
+ {
55
+ $args = array(
56
+ 'public' => true,
57
+ );
58
+ $exclude_post_types = apply_filters( 'custom_permalinks_exclude_post_type',
59
+ $post->post_type
60
+ );
61
+ $exclude_posts = apply_filters( 'custom_permalinks_exclude_posts',
62
+ $post
63
+ );
64
+ $public_post_types = get_post_types( $args, 'objects' );
65
+
66
+ if ( isset( $this->permalink_metabox ) && 1 === $this->permalink_metabox ) {
67
+ $check_availability = true;
68
+ } elseif ( 'attachment' === $post->post_type ) {
69
+ $check_availability = true;
70
+ } elseif ( $post->ID === intval( get_option( 'page_on_front' ) ) ) {
71
+ $check_availability = true;
72
+ } elseif ( ! isset( $public_post_types[$post->post_type] ) ) {
73
+ $check_availability = true;
74
+ } elseif ( '__true' === $exclude_post_types ) {
75
+ $check_availability = true;
76
+ } elseif ( is_bool( $exclude_posts ) && $exclude_posts ) {
77
+ $check_availability = true;
78
+ } else {
79
+ $check_availability = false;
80
+ }
81
 
82
+ return $check_availability;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  }
84
 
85
+ /**
86
+ * Register meta box(es).
87
+ *
88
+ * @since 1.4.0
89
+ * @access public
90
+ */
91
+ public function permalink_edit_box()
92
+ {
93
+ add_meta_box( 'custom-permalinks-edit-box',
94
+ __( 'Permalink', 'custom-permalinks' ),
95
+ array( $this, 'meta_edit_form' ), null, 'normal', 'high',
96
+ array(
97
+ '__back_compat_meta_box' => false,
98
+ )
99
+ );
100
  }
 
101
 
102
+ /**
103
+ * Set the meta_keys to protected which is created by the plugin.
104
+ *
105
+ * @since 1.4.0
106
+ * @access public
107
+ *
108
+ * @param bool $protected Whether the key is protected or not.
109
+ * @param string $meta_key Meta key.
110
+ *
111
+ * @return bool `true` for the custom_permalink key.
112
+ */
113
+ public function protect_meta( $protected, $meta_key )
114
+ {
115
+ if ( 'custom_permalink' === $meta_key ) {
116
+ $protected = true;
117
+ }
118
 
119
+ return $protected;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  }
121
 
122
+ /**
123
+ * Save per-post options.
124
+ *
125
+ * @access public
126
+ *
127
+ * @param int $post_id Post ID.
128
+ */
129
+ public function save_post( $post_id )
130
+ {
131
+ if ( ! isset( $_REQUEST['custom_permalinks_edit'] ) ) {
132
+ return;
133
+ }
134
 
135
+ $this->delete_permalink( $post_id );
136
+
137
+ $cp_frontend = new Custom_Permalinks_Frontend();
138
+ $original_link = $cp_frontend->original_post_link( $post_id );
139
+ if ( $_REQUEST['custom_permalink']
140
+ && $_REQUEST['custom_permalink'] != $original_link
141
+ ) {
142
+ add_post_meta( $post_id, 'custom_permalink',
143
+ str_replace( '%2F', '/', urlencode(
144
+ ltrim( stripcslashes( $_REQUEST['custom_permalink'] ), '/' )
145
+ ) )
146
+ );
147
+ }
148
  }
149
 
150
+ /**
151
+ * Delete Post Permalink.
152
+ *
153
+ * @access public
154
+ *
155
+ * @param int $post_id Post ID.
156
+ */
157
+ public function delete_permalink( $post_id )
158
+ {
159
+ delete_post_meta( $post_id, 'custom_permalink' );
160
  }
 
161
 
162
+ /**
163
+ * Result Permalink HTML Form for classic editor and Gutenberg.
164
+ *
165
+ * @since 1.6.0
166
+ * @access private
167
+ *
168
+ * @param object $post WP Post Object.
169
+ * @param bool $meta_box Show whether calls from clasic WordPress or Gutenberg.
170
+ *
171
+ * @return string Permalink Form HTML.
172
+ */
173
+ private function get_permalink_html( $post, $meta_box = false )
174
+ {
175
+ $post_id = $post->ID;
176
+ $permalink = get_post_meta( $post_id, 'custom_permalink', true );
177
+
178
+ ob_start();
179
 
180
+ $cp_frontend = new Custom_Permalinks_Frontend();
181
+ if ( 'page' === $post->post_type ) {
182
+ $original_permalink = $cp_frontend->original_page_link( $post_id );
183
+ $view_post = __( 'View Page', 'custom-permalinks' );
184
+ } else {
185
+ $post_type_name = '';
186
+ $post_type_object = get_post_type_object( $post->post_type );
187
+ if ( is_object($post_type_object) && isset( $post_type_object->labels )
188
+ && isset( $post_type_object->labels->singular_name )
189
+ ) {
190
+ $post_type_name = ' ' . $post_type_object->labels->singular_name;
191
+ } elseif ( is_object($post_type_object)
192
+ && isset( $post_type_object->label )
193
+ ) {
194
+ $post_type_name = ' ' . $post_type_object->label;
195
+ }
196
+
197
+ $original_permalink = $cp_frontend->original_post_link( $post_id );
198
+ $view_post = __( 'View', 'custom-permalinks' ) . $post_type_name;
199
+ }
200
+ $this->get_permalink_form( $permalink, $original_permalink, false,
201
+ $post->post_name
202
+ );
203
+
204
+ $content = ob_get_contents();
205
+ ob_end_clean();
206
+
207
+ if ( 'trash' !== $post->post_status ) {
208
+ wp_enqueue_script( 'custom-permalinks-form',
209
+ plugins_url( '/js/script-form.min.js', __FILE__ ), array(),
210
+ false, true
211
+ );
212
+
213
+ $home_url = trailingslashit( home_url() );
214
+ if ( isset( $permalink ) && ! empty( $permalink ) ) {
215
+ $view_post_link = $home_url . $permalink;
216
+ } else {
217
+ if ( 'draft' === $post->post_status ) {
218
+ $view_post = 'Preview';
219
+ $view_post_link = $home_url . '?';
220
+ if ( 'page' === $post->post_type ) {
221
+ $view_post_link .= 'page_id';
222
+ } elseif ( 'post' === $post->post_type ) {
223
+ $view_post_link .= 'p';
224
+ } else {
225
+ $view_post_link .= 'post_type=' . $post->post_type . '&p';
226
+ }
227
+ $view_post_link .= '=' . $post_id . '&preview=true';
228
+ } else {
229
+ $view_post_link = $home_url . $original_permalink;
230
+ }
231
+ }
232
+
233
+ $content .= ' <span id="view-post-btn">' .
234
+ '<a href="' . $view_post_link . '" class="button button-small" target="_blank">' . $view_post .'</a>' .
235
+ '</span><br>';
236
+ if ( true === $meta_box ) {
237
+ $content .= '<style>.editor-post-permalink,.cp-permalink-hidden{display:none;}</style>';
238
+ }
239
+ }
240
+
241
+ return '<strong>' . __( 'Permalink:', 'custom-permalinks' ) . '</strong> ' . $content;
242
  }
 
243
 
244
+ /**
245
+ * Per-post/page options (Wordpress > 2.9).
246
+ *
247
+ * @access public
248
+ *
249
+ * @param string $html WP Post Permalink HTML.
250
+ * @param int $post_id Post ID.
251
+ *
252
+ * @return string Edit Form string.
253
+ */
254
+ public function sample_permalink_html( $html, $post_id )
255
+ {
256
+ $post = get_post( $post_id );
257
+
258
+ $disable_cp = $this->exclude_custom_permalinks( $post );
259
+ $this->permalink_metabox = 1;
260
+ if ( $disable_cp ) {
261
+ return $html;
262
+ }
263
 
264
+ $output_content = $this->get_permalink_html( $post );
 
 
 
 
265
 
266
+ return $output_content;
 
 
267
  }
268
+
269
+ /**
270
+ * Adds the Permalink Edit Meta box for the user with validating the
271
+ * PostTypes to make compatibility with Gutenberg.
272
+ *
273
+ * @access public
274
+ *
275
+ * @param object $post WP Post Object.
276
+ */
277
+ public function meta_edit_form( $post )
278
+ {
279
+ $disable_cp = $this->exclude_custom_permalinks( $post );
280
+ if ( $disable_cp ) {
281
+ wp_enqueue_script( 'custom-permalinks-form',
282
+ plugins_url( '/js/script-form.min.js', __FILE__ ), array(),
283
+ false, true
284
+ );
285
+
286
+ return;
287
+ }
288
+
289
+ $screen = get_current_screen();
290
+ if ( 'add' === $screen->action ) {
291
+ echo '<input value="add" type="hidden" name="custom-permalinks-add" id="custom-permalinks-add" />';
292
+ }
293
+
294
+ $output_content = $this->get_permalink_html( $post, true );
295
+
296
+ echo $output_content;
297
  }
298
 
299
+ /**
300
+ * Per-post options (Wordpress < 2.9).
301
+ *
302
+ * @access public
303
+ */
304
+ public function post_options()
305
+ {
306
+ global $post;
307
+
308
+ if ( is_object( $post ) ) {
309
+ $post_id = $post->ID;
310
+ } else {
311
+ $post_id = $post;
312
+ }
313
+
314
+ $permalink = get_post_meta( $post_id, 'custom_permalink', true );
315
  ?>
316
+ <div class="postbox closed">
317
+ <h3>
318
+ <?php
319
+ esc_html_e( 'Custom Permalink', 'custom-permalinks' );
320
+ ?>
321
+ </h3>
322
+
323
+ <div class="inside">
324
+ <?php
325
+ $cp_frontend = new Custom_Permalinks_Frontend();
326
+ $this->get_permalink_form( $permalink,
327
+ $cp_frontend->original_post_link( $post_id )
328
+ );
329
+ ?>
330
+ </div>
331
+ </div>
332
+ <?php
333
  }
334
 
335
+ /**
336
+ * Per-page options (Wordpress < 2.9).
337
+ *
338
+ * @access public
339
+ */
340
+ public function page_options()
341
+ {
342
+ global $post;
343
+
344
+ if ( is_object( $post ) ) {
345
+ $post_id = $post->ID;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
  } else {
347
+ $post_id = $post;
348
  }
 
349
 
350
+ $permalink = get_post_meta( $post_id, 'custom_permalink', true );
351
+ ?>
352
+ <div class="postbox closed">
353
+ <h3>
354
+ <?php
355
+ esc_html_e( 'Custom Permalink', 'custom-permalinks' );
356
+ ?>
357
+ </h3>
358
+ <div class="inside">
359
+ <?php
360
+ $cp_frontend = new Custom_Permalinks_Frontend();
361
+ $page_permalink = $cp_frontend->original_page_link( $post_id );
362
+ $this->get_permalink_form( $permalink, $page_permalink );
363
+ ?>
364
+ </div>
365
+ </div>
366
+ <?php
367
  }
368
 
369
+ /**
370
+ * Per-category/tag options.
371
+ *
372
+ * @access public
373
+ *
374
+ * @param object $object Term Object.
375
+ */
376
+ public function term_options( $object )
377
+ {
378
+ $permalink = '';
379
+ $original_permalink = '';
380
+ if ( is_object( $object ) && isset( $object->term_id ) ) {
381
+ $cp_frontend = new Custom_Permalinks_Frontend();
382
+ if ( $object->term_id ) {
383
+ $permalink = $cp_frontend->term_permalink( $object->term_id );
384
+ $original_permalink = $cp_frontend->original_term_link(
385
+ $object->term_id
386
+ );
387
+ }
388
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
 
390
+ $this->get_permalink_form( $permalink, $original_permalink );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
391
 
392
+ // Move the save button to above this form
393
+ wp_enqueue_script( 'jquery' );
394
+ ?>
395
+ <script type="text/javascript">
396
+ jQuery(document).ready(function() {
397
+ var button = jQuery('#custom_permalink_form').parent().find('.submit');
398
+ button.remove().insertAfter(jQuery('#custom_permalink_form'));
399
+ });
400
+ </script>
401
+ <?php
402
  }
403
 
404
+ /**
405
+ * Helper function to render form.
406
+ *
407
+ * @access private
408
+ *
409
+ * @param string $permalink Permalink which is created by the plugin.
410
+ * @param string $original Permalink which set by WordPress.
411
+ * @param bool $render_containers Shows Post/Term Edit.
412
+ * @param string $postname Post Name.
413
+ */
414
+ private function get_permalink_form( $permalink, $original = '',
415
+ $render_containers = true, $postname = ''
416
+ ) {
417
+ $encoded_permalink = htmlspecialchars( urldecode( $permalink ) );
418
+ $home_url = trailingslashit( home_url() );
419
+
420
+ echo '<input value="true" type="hidden" name="custom_permalinks_edit" />' .
421
+ '<input value="' . $home_url . '" type="hidden" name="custom_permalinks_home_url" id="custom_permalinks_home_url" />' .
422
+ '<input value="' . $encoded_permalink . '" type="hidden" name="custom_permalink" id="custom_permalink" />';
423
+
424
+ if ( $render_containers ) {
425
+ echo '<table class="form-table" id="custom_permalink_form">' .
426
+ '<tr>' .
427
+ '<th scope="row">' . __( 'Custom Permalink', 'custom-permalinks' ) . '</th>' .
428
+ '<td>';
429
+ }
430
+ if ( '' === $permalink ) {
431
+ $original = $this->check_conflicts( $original );
432
+ }
433
 
434
+ if ( $permalink ) {
435
+ $post_slug = htmlspecialchars( urldecode( $permalink ) );
436
+ $original_encoded_url = htmlspecialchars( urldecode( $original ) );
437
+ } else {
438
+ $post_slug = htmlspecialchars( urldecode( $original ) );
439
+ $original_encoded_url = $post_slug;
440
+ }
441
 
442
+ wp_enqueue_script( 'custom-permalinks-form',
443
+ plugins_url( '/js/script-form.min.js', __FILE__ ), array(), false, true
444
+ );
445
+ $postname_html = '';
446
+ if ( isset( $postname ) && '' !== $postname ) {
447
+ $postname_html = '<input type="hidden" id="new-post-slug" class="text" value="' . $postname . '" />';
448
+ }
449
+
450
+ $field_style = 'width: 250px;';
451
+ if ( !$permalink ) {
452
+ $field_style .= ' color: #ddd;';
453
+ }
454
+
455
+ echo $home_url .
456
+ '<span id="editable-post-name" title="Click to edit this part of the permalink">' .
457
+ $postname_html .
458
+ '<input type="hidden" id="original-permalink" value="' . $original_encoded_url . '" />' .
459
+ '<input type="text" id="custom-permalinks-post-slug" class="text" value="' . $post_slug . '" style="' . $field_style . '" />' .
460
+ '</span>';
461
+
462
+ if ( $render_containers ) {
463
+ echo '<br />' .
464
+ '<small>' . __( "Leave blank to disable", "custom-permalinks" ) . '</small>' .
465
+ '</td>' .
466
+ '</tr>' .
467
+ '</table>';
468
+ }
469
  }
470
 
471
+ /**
472
+ * Save term (common to tags and categories).
473
+ *
474
+ * @since 1.6.0
475
+ * @access public
476
+ *
477
+ * @param string $term_id Term ID.
478
+ */
479
+ public function save_term( $term_id )
480
+ {
481
+ $term = get_term( $term_id );
482
+ if ( isset( $term ) && isset( $term->taxonomy ) ) {
483
+ $taxonomy_name = $term->taxonomy;
484
+ if ( 'category' === $taxonomy_name
485
+ || 'post_tag' === $taxonomy_name
486
+ ) {
487
+ if ( 'post_tag' === $taxonomy_name ) {
488
+ $taxonomy_name = 'tag';
489
+ }
490
+
491
+ $new_permalink = ltrim(
492
+ stripcslashes( $_REQUEST['custom_permalink'] ), '/'
493
+ );
494
+ if ( empty( $new_permalink ) || '' === $new_permalink ) {
495
+ return;
496
+ }
497
+
498
+ $cp_frontend = new Custom_Permalinks_Frontend();
499
+ $old_permalink = $cp_frontend->original_term_link( $term_id );
500
+ if ( $new_permalink === $old_permalink ) {
501
+ return;
502
+ }
503
+
504
+ $this->delete_term_permalink( $term_id );
505
+
506
+ $permalink = str_replace( '%2F', '/', urlencode( $new_permalink ) );
507
+ $table = get_option( 'custom_permalink_table' );
508
+
509
+ if ( $permalink ) {
510
+ $table[$permalink] = array(
511
+ 'id' => $term_id,
512
+ 'kind' => $taxonomy_name,
513
+ 'slug' => $term->slug,
514
+ );
515
+ }
516
+
517
+ update_option( 'custom_permalink_table', $table );
518
+ }
519
  }
 
520
  }
521
+
522
+ /**
523
+ * Delete term.
524
+ *
525
+ * @access public
526
+ *
527
+ * @param int $term_id Term ID.
528
+ */
529
+ public function delete_term_permalink( $term_id )
530
+ {
531
+ $table = get_option( 'custom_permalink_table' );
532
+ if ( $table ) {
533
+ foreach ( $table as $link => $info ) {
534
+ if ( $info['id'] === $term_id ) {
535
+ unset( $table[$link] );
536
+ break;
537
+ }
538
+ }
539
+ }
540
+
541
+ update_option( 'custom_permalink_table', $table );
542
  }
543
 
544
+ /**
545
+ * Check Conflicts and resolve it (e.g: Polylang) UPDATED for Polylang
546
+ * hide_default setting.
547
+ *
548
+ * @since 1.2.0
549
+ * @access public
550
+ *
551
+ * @return string requested URL by removing the language/ from it if exist.
552
+ */
553
+ public function check_conflicts( $requested_url = '' )
554
+ {
555
+ if ( '' === $requested_url ) {
556
+ return;
557
+ }
558
 
559
+ // Check if the Polylang Plugin is installed so, make changes in the URL
560
+ if ( defined( 'POLYLANG_VERSION' ) ) {
561
+ $polylang_config = get_option( 'polylang' );
562
+ if ( 1 === $polylang_config['force_lang'] ) {
563
+ if ( false !== strpos( $requested_url, 'language/' ) ) {
564
+ $requested_url = str_replace( 'language/', '', $requested_url );
565
+ }
566
+
567
+ /*
568
+ * Check if `hide_default` is `true` and the current language is not
569
+ * the default. Otherwise remove the lang code from the url.
570
+ */
571
+ if ( 1 === $polylang_config['hide_default'] ) {
572
+ $current_language = '';
573
+ if ( function_exists( 'pll_current_language' ) ) {
574
+ // get current language
575
+ $current_language = pll_current_language();
576
+ }
577
+
578
+ // get default language
579
+ $default_language = $polylang_config['default_lang'];
580
+ if ( $current_language !== $default_language ) {
581
+ $remove_lang = ltrim( strstr( $requested_url, '/' ), '/' );
582
+ if ( '' != $remove_lang ) {
583
+ return $remove_lang;
584
+ }
585
+ }
586
+ } else {
587
+ $remove_lang = ltrim( strstr( $requested_url, '/' ), '/' );
588
+ if ( '' != $remove_lang ) {
589
+ return $remove_lang;
590
+ }
591
+ }
592
+ }
593
  }
594
 
595
+ return $requested_url;
596
+ }
597
+
598
+ /**
599
+ * Refresh Permalink using AJAX Call.
600
+ *
601
+ * @since 1.6.0
602
+ * @access public
603
+ *
604
+ * @param object $data Contains post id with some default REST Values.
605
+ */
606
+ public function refresh_meta_form( $data )
607
+ {
608
+ if ( isset( $data['id'] ) && is_numeric( $data['id'] ) ) {
609
+ $post = get_post( $data['id'] );
610
+ $all_permalinks = array();
611
+ $all_permalinks['custom_permalink'] = get_post_meta( $data['id'],
612
+ 'custom_permalink', true
613
+ );
614
+
615
+ if ( ! $all_permalinks['custom_permalink'] ) {
616
+ if ( 'draft' === $post->post_status ) {
617
+ $view_post_link = '?';
618
+ if ( 'page' === $post->post_type ) {
619
+ $view_post_link .= 'page_id';
620
+ } elseif ( 'post' === $post->post_type ) {
621
+ $view_post_link .= 'p';
622
+ } else {
623
+ $view_post_link .= 'post_type=' . $post->post_type . '&p';
624
+ }
625
+ $view_post_link .= '=' . $data['id'] . '&preview=true';
626
+
627
+ $all_permalinks['preview_permalink'] = $view_post_link;
628
+ }
629
  }
630
+
631
+ $cp_frontend = new Custom_Permalinks_Frontend;
632
+ if ( 'page' === $post->post_type ) {
633
+ $all_permalinks['original_permalink'] = $cp_frontend->original_page_link(
634
+ $data['id']
635
+ );
636
+ } else {
637
+ $all_permalinks['original_permalink'] = $cp_frontend->original_post_link(
638
+ $data['id']
639
+ );
640
+ }
641
+
642
+ echo json_encode( $all_permalinks );
643
+ exit;
644
+ }
645
+ }
646
+
647
+ /**
648
+ * Added Custom Endpoints for refreshing the permalink.
649
+ *
650
+ * @since 1.6.0
651
+ * @access public
652
+ */
653
+ public function rest_edit_form()
654
+ {
655
+ register_rest_route( 'custom-permalinks/v1', '/get-permalink/(?P<id>\d+)',
656
+ array(
657
+ 'methods' => 'GET',
658
+ 'callback' => array( $this, 'refresh_meta_form' ),
659
+ )
660
+ );
661
+ }
662
+
663
+ /**
664
+ * Delete the Permalink for the Page selected as the Static Homepage.
665
+ *
666
+ * @since 1.6.0
667
+ * @access public
668
+ *
669
+ * @param int $prev_homepage_id Page ID of previously set Front Page.
670
+ * @param int $new_homepage_id Page ID of current Front Page.
671
+ */
672
+ public function static_homepage( $prev_homepage_id, $new_homepage_id ) {
673
+ if ( $prev_homepage_id !== $new_homepage_id ) {
674
+ $this->delete_permalink( $new_homepage_id );
675
  }
 
676
  }
 
 
677
  }
frontend/class-custom-permalinks-frontend.php CHANGED
@@ -1,523 +1,767 @@
1
  <?php
2
  /**
3
- * @package CustomPermalinks\Frontend
4
  */
5
 
6
- class Custom_Permalinks_Frontend {
7
-
8
- /**
9
- * Initialize WordPress Hooks
10
- *
11
- * @access public
12
- * @since 1.2
13
- * @return void
14
- */
15
- public function init() {
16
- add_filter( 'request', array( $this, 'parse_request' ), 10, 1 );
17
-
18
- add_action( 'template_redirect', array( $this, 'make_redirect' ), 5 );
19
-
20
- add_filter( 'post_link',
21
- array( $this, 'custom_permalinks_post_link' ), 10, 2
22
- );
23
- add_filter( 'post_type_link',
24
- array( $this, 'custom_permalinks_post_link' ), 10, 2
25
- );
26
- add_filter( 'page_link',
27
- array( $this, 'custom_permalinks_page_link' ), 10, 2
28
- );
29
-
30
- add_filter(
31
- 'tag_link', array( $this, 'custom_permalinks_term_link' ), 10, 2
32
- );
33
- add_filter( 'category_link',
34
- array( $this, 'custom_permalinks_term_link' ), 10, 2
35
- );
36
-
37
- add_filter( 'user_trailingslashit',
38
- array( $this, 'custom_permalinks_trailingslash' ), 10, 2
39
- );
40
- }
41
-
42
- /**
43
- * Filter to rewrite the query if we have a matching post
44
- *
45
- * @access public
46
- * @since 0.1
47
- * @return void
48
- */
49
- public function parse_request( $query ) {
50
- global $wpdb;
51
- global $_CPRegisteredURL;
52
-
53
- // First, search for a matching custom permalink,
54
- // and if found, generate the corresponding original URL
55
-
56
- $original_url = NULL;
57
-
58
- // Get request URI, strip parameters and /'s
59
- $url = parse_url( get_bloginfo( 'url' ) );
60
- $url = isset( $url['path'] ) ? $url['path'] : '';
61
- $request = ltrim( substr( $_SERVER['REQUEST_URI'], strlen( $url ) ), '/' );
62
- $pos = strpos( $request, '?' );
63
- if ( $pos ) {
64
- $request = substr( $request, 0, $pos );
65
- }
66
 
67
- if ( ! $request ) {
68
- return $query;
69
- }
70
 
71
- $ignore = apply_filters( 'custom_permalinks_request_ignore', $request );
72
 
73
- if ( '__true' === $ignore ) {
74
- return $query;
 
 
 
 
 
 
 
 
 
75
  }
76
 
77
- if ( defined( 'POLYLANG_VERSION' ) ) {
78
- require_once(
79
- CUSTOM_PERMALINKS_PATH . 'frontend/class-custom-permalinks-form.php'
80
- );
81
- $cp_form = new Custom_Permalinks_Form();
82
- $request = $cp_form->custom_permalinks_check_conflicts( $request );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  }
84
- $request_noslash = preg_replace( '@/+@','/', trim( $request, '/' ) );
85
-
86
- $sql = $wpdb->prepare( "SELECT p.ID, pm.meta_value, p.post_type, p.post_status " .
87
- " FROM $wpdb->posts AS p INNER JOIN $wpdb->postmeta AS pm ON (pm.post_id = p.ID) " .
88
- " WHERE pm.meta_key = 'custom_permalink' " .
89
- " AND (pm.meta_value = '%s' OR pm.meta_value = '%s') " .
90
- " AND p.post_status != 'trash' AND p.post_type != 'nav_menu_item' " .
91
- " ORDER BY FIELD(post_status,'publish','private','pending','draft','auto-draft','inherit')," .
92
- " FIELD(post_type,'post','page') LIMIT 1", $request_noslash, $request_noslash . "/" );
93
-
94
- $posts = $wpdb->get_results( $sql );
95
-
96
- $remove_like_query = apply_filters( 'cp_remove_like_query', '__true' );
97
- if ( ! $posts && '__true' === $remove_like_query ) {
98
- $sql = $wpdb->prepare( "SELECT p.ID, pm.meta_value, p.post_type, p.post_status FROM $wpdb->posts AS p " .
99
- " LEFT JOIN $wpdb->postmeta AS pm ON (p.ID = pm.post_id) WHERE " .
100
- " meta_key = 'custom_permalink' AND meta_value != '' AND " .
101
- " ( LOWER(meta_value) = LEFT(LOWER('%s'), LENGTH(meta_value)) OR " .
102
- " LOWER(meta_value) = LEFT(LOWER('%s'), LENGTH(meta_value)) ) " .
103
- " AND post_status != 'trash' AND post_type != 'nav_menu_item'" .
104
- " ORDER BY LENGTH(meta_value) DESC, " .
105
- " FIELD(post_status,'publish','private','pending','draft','auto-draft','inherit')," .
106
- " FIELD(post_type,'post','page'), p.ID ASC LIMIT 1",
107
- $request_noslash, $request_noslash . "/" );
108
-
109
- $posts = $wpdb->get_results( $sql );
 
 
 
 
 
 
 
110
  }
111
 
112
- if ( $posts ) {
113
- // A post matches our request
114
- // Preserve this url for later if it's the same as the permalink (no extra stuff)
115
- if ( $request_noslash == trim( $posts[0]->meta_value, '/' ) ) {
116
- $_CPRegisteredURL = $request;
117
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
- if ( 'draft' == $posts[0]->post_status ) {
120
- if ( 'page' == $posts[0]->post_type ) {
121
- $original_url = '?page_id=' . $posts[0]->ID;
122
- } else {
123
- $original_url = '?post_type=' . $posts[0]->post_type . '&p=' . $posts[0]->ID;
124
  }
125
- } else {
126
- $post_meta = trim( strtolower( $posts[0]->meta_value ), '/' );
127
- if ( $posts[0]->post_type == 'page' ) {
128
- $get_original_url = $this->custom_permalinks_original_page_link( $posts[0]->ID );
129
- $original_url = preg_replace( '@/+@', '/',
130
- str_replace( $post_meta, $get_original_url, strtolower( $request_noslash ) )
131
- );
132
- } else {
133
- $get_original_url = $this->custom_permalinks_original_post_link( $posts[0]->ID );
134
- $original_url = preg_replace( '@/+@', '/',
135
- str_replace( $post_meta, $get_original_url, strtolower( $request_noslash ) )
136
- );
137
  }
138
- }
139
- }
140
 
141
- if ( NULL === $original_url ) {
142
- // See if any terms have a matching permalink
143
- $table = get_option( 'custom_permalink_table' );
144
- if ( ! $table ) {
145
- return $query;
146
- }
147
-
148
- foreach ( array_keys( $table ) as $permalink ) {
149
- if ( $permalink == substr( $request_noslash, 0, strlen( $permalink ) )
150
- || $permalink == substr( $request_noslash . '/', 0, strlen( $permalink ) ) ) {
151
- $term = $table[$permalink];
152
-
153
- // Preserve this url for later if it's the same as the permalink (no extra stuff)
154
- if ( $request_noslash == trim( $permalink, '/' ) ) {
155
- $_CPRegisteredURL = $request;
156
- }
157
-
158
- if ( 'category' == $term['kind'] ) {
159
- $category_link = $this->custom_permalinks_original_category_link( $term['id'] );
160
- } else {
161
- $category_link = $this->custom_permalinks_original_tag_link( $term['id'] );
162
- }
163
-
164
- $original_url = str_replace(
165
- trim( $permalink, '/' ), $category_link, trim( $request, '/' )
166
- );
 
 
 
 
 
 
 
 
167
  }
168
- }
169
- }
170
 
171
- if ( NULL !== $original_url ) {
172
- $original_url = str_replace( '//', '/', $original_url );
173
-
174
- $pos = strpos( $_SERVER['REQUEST_URI'], '?' );
175
- if ( false !== $pos ) {
176
- $query_vars = substr( $_SERVER['REQUEST_URI'], $pos + 1 );
177
- $original_url .= ( strpos( $original_url, '?' ) === false ? '?' : '&' ) . $query_vars;
178
- }
179
-
180
- // Now we have the original URL, run this back through WP->parse_request,
181
- // in order to parse parameters properly.
182
- // We set $_SERVER variables to fool the function.
183
- $old_request_uri = $_SERVER['REQUEST_URI'];
184
- $old_query_string = '';
185
- if ( isset( $_SERVER['QUERY_STRING'] ) ) {
186
- $old_query_string = $_SERVER['QUERY_STRING'];
187
- }
188
- $_SERVER['REQUEST_URI'] = '/' . ltrim( $original_url, '/' );
189
- $path_info = apply_filters( 'custom_permalinks_path_info', '__false' );
190
- if ( '__false' !== $path_info ) {
191
- $_SERVER['PATH_INFO'] = '/' . ltrim( $original_url, '/' );
192
- }
193
-
194
- $_SERVER['QUERY_STRING'] = '';
195
- $pos = strpos( $original_url, '?' );
196
- if ( false !== $pos ) {
197
- $_SERVER['QUERY_STRING'] = substr( $original_url, $pos + 1 );
198
- }
199
-
200
- parse_str( $_SERVER['QUERY_STRING'], $query_array );
201
- $old_values = array();
202
- if ( is_array( $query_array ) ) {
203
- foreach ( $query_array as $key => $value ) {
204
- $old_values[$key] = $_REQUEST[$key];
205
- $_REQUEST[$key] = $_GET[$key] = $value;
206
  }
207
- }
208
-
209
- // Re-run the filter, now with original environment in place
210
- remove_filter( 'request', array( $this, 'parse_request' ), 10, 1 );
211
- global $wp;
212
- $wp->parse_request();
213
- $query = $wp->query_vars;
214
- add_filter( 'request', array( $this, 'parse_request' ), 10, 1 );
215
-
216
- // Restore values
217
- $_SERVER['REQUEST_URI'] = $old_request_uri;
218
- $_SERVER['QUERY_STRING'] = $old_query_string;
219
- foreach ( $old_values as $key => $value ) {
220
- $_REQUEST[$key] = $value;
221
- }
222
- }
223
 
224
- return $query;
225
- }
226
-
227
- /**
228
- * Action to redirect to the custom permalink
229
- *
230
- * @access public
231
- * @since 0.1
232
- * @return void
233
- */
234
- public function make_redirect() {
235
- global $wpdb;
236
-
237
- $custom_permalink = '';
238
- $original_permalink = '';
239
-
240
- // Get request URI, strip parameters
241
- $url = parse_url( get_bloginfo( 'url' ) );
242
- $url = isset( $url['path'] ) ? $url['path'] : '';
243
- $request = ltrim( substr( $_SERVER['REQUEST_URI'], strlen( $url ) ), '/' );
244
- $pos = strpos( $request, '?' );
245
- if ( $pos ) {
246
- $request = substr( $request, 0, $pos );
247
- }
 
 
 
 
248
 
249
- if ( defined( 'POLYLANG_VERSION' ) ) {
250
- require_once(
251
- CUSTOM_PERMALINKS_PATH . 'frontend/class-custom-permalinks-form.php'
252
- );
253
- $cp_form = new Custom_Permalinks_Form();
254
- $request = $cp_form->custom_permalinks_check_conflicts( $request );
255
- }
256
- $request_noslash = preg_replace( '@/+@','/', trim( $request, '/' ) );
257
-
258
- $sql = $wpdb->prepare( "SELECT p.ID, pm.meta_value, p.post_type, p.post_status " .
259
- " FROM $wpdb->posts AS p INNER JOIN $wpdb->postmeta AS pm ON (pm.post_id = p.ID) " .
260
- " WHERE pm.meta_key = 'custom_permalink' " .
261
- " AND (pm.meta_value = '%s' OR pm.meta_value = '%s') " .
262
- " AND p.post_status != 'trash' AND p.post_type != 'nav_menu_item' " .
263
- " ORDER BY FIELD(post_status,'publish','private','draft','auto-draft','inherit')," .
264
- " FIELD(post_type,'post','page') LIMIT 1", $request_noslash, $request_noslash . "/" );
265
-
266
- $posts = $wpdb->get_results( $sql );
267
-
268
- $remove_like_query = apply_filters( 'cp_remove_like_query', '__true' );
269
- if ( ! $posts && '__false' !== $remove_like_query ) {
270
- $sql = $wpdb->prepare( "SELECT p.ID, pm.meta_value, p.post_type, p.post_status FROM $wpdb->posts AS p " .
271
- " LEFT JOIN $wpdb->postmeta AS pm ON (p.ID = pm.post_id) WHERE " .
272
- " meta_key = 'custom_permalink' AND meta_value != '' AND " .
273
- " ( LOWER(meta_value) = LEFT(LOWER('%s'), LENGTH(meta_value)) OR " .
274
- " LOWER(meta_value) = LEFT(LOWER('%s'), LENGTH(meta_value)) ) " .
275
- " AND post_status != 'trash' AND post_type != 'nav_menu_item'" .
276
- " ORDER BY LENGTH(meta_value) DESC, " .
277
- " FIELD(post_status,'publish','private','draft','auto-draft','inherit')," .
278
- " FIELD(post_type,'post','page'), p.ID ASC LIMIT 1",
279
- $request_noslash, $request_noslash . "/" );
280
-
281
- $posts = $wpdb->get_results( $sql );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
  }
283
 
284
- if ( ! isset( $posts[0]->ID ) || ! isset( $posts[0]->meta_value )
285
- || empty( $posts[0]->meta_value ) ) {
286
- global $wp_query;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
 
288
- // If the post/tag/category we're on has a custom permalink, get it and
289
- // check against the request
290
- if ( ( is_single() || is_page() ) && ! empty( $wp_query->post ) ) {
291
- $post = $wp_query->post;
292
- $custom_permalink = get_post_meta( $post->ID, 'custom_permalink', true );
293
- if ( $post->post_type == 'page' ) {
294
- $original_permalink = $this->custom_permalinks_original_page_link( $post->ID );
295
- } else {
296
- $original_permalink = $this->custom_permalinks_original_post_link( $post->ID );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
  }
298
- } elseif ( is_tag() || is_category() ) {
299
- $theTerm = $wp_query->get_queried_object();
300
- $custom_permalink = $this->custom_permalinks_permalink_for_term( $theTerm->term_id );
301
- if ( is_tag() ) {
302
- $original_permalink = $this->custom_permalinks_original_tag_link( $theTerm->term_id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  } else {
304
- $original_permalink = $this->custom_permalinks_original_category_link( $theTerm->term_id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
  }
306
- }
307
- } else {
308
- $custom_permalink = $posts[0]->meta_value;
309
- if ( 'page' == $posts[0]->post_type ) {
310
- $original_permalink = $this->custom_permalinks_original_page_link( $posts[0]->ID );
311
- } else {
312
- $original_permalink = $this->custom_permalinks_original_post_link( $posts[0]->ID );
313
- }
314
  }
315
 
316
- if ( $custom_permalink
317
- && ( substr( $request, 0, strlen( $custom_permalink ) ) != $custom_permalink
318
- || $request == $custom_permalink . '/' ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
 
320
- // Request doesn't match permalink - redirect
321
- $url = $custom_permalink;
322
 
323
- if ( substr( $request, 0, strlen( $original_permalink ) ) == $original_permalink
324
- && trim( $request, '/' ) != trim( $original_permalink, '/' ) ) {
325
- // This is the original link; we can use this url to derive the new one
326
- $url = preg_replace( '@//*@', '/', str_replace( trim( $original_permalink, '/' ), trim( $custom_permalink, '/' ), $request ) );
327
- $url = preg_replace( '@([^?]*)&@', '\1?', $url );
328
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
329
 
330
- // Append any query compenent
331
- $url .= strstr( $_SERVER['REQUEST_URI'], '?' );
332
 
333
- wp_redirect( home_url() . '/' . $url, 301 );
334
- exit();
335
  }
336
- }
337
-
338
- /**
339
- * Filter to replace the post permalink with the custom one
340
- *
341
- * @access public
342
- * @return string
343
- */
344
- public function custom_permalinks_post_link( $permalink, $post ) {
345
- $custom_permalink = get_post_meta( $post->ID, 'custom_permalink', true );
346
- if ( $custom_permalink ) {
347
- $post_type = isset( $post->post_type ) ? $post->post_type : 'post';
348
- $language_code = apply_filters( 'wpml_element_language_code', null, array( 'element_id' => $post->ID, 'element_type' => $post_type ) );
349
- if ( $language_code )
350
- return apply_filters( 'wpml_permalink', trailingslashit( home_url() ) . $custom_permalink, $language_code );
351
- else
352
- return apply_filters( 'wpml_permalink', trailingslashit( home_url() ) . $custom_permalink );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
  }
354
 
355
- return $permalink;
356
- }
357
-
358
- /**
359
- * Filter to replace the page permalink with the custom one
360
- *
361
- * @access public
362
- * @return string
363
- */
364
- public function custom_permalinks_page_link( $permalink, $page ) {
365
- $custom_permalink = get_post_meta( $page, 'custom_permalink', true );
366
- if ( $custom_permalink ) {
367
- $language_code = apply_filters( 'wpml_element_language_code', null, array( 'element_id' => $page, 'element_type' => 'page' ) );
368
- if ( $language_code )
369
- return apply_filters( 'wpml_permalink', trailingslashit( home_url() ) . $custom_permalink, $language_code );
370
- else
371
- return apply_filters( 'wpml_permalink', trailingslashit( home_url() ) . $custom_permalink );
 
 
 
 
 
 
 
 
 
 
 
372
  }
373
 
374
- return $permalink;
375
- }
376
-
377
- /**
378
- * Filter to replace the term permalink with the custom one
379
- *
380
- * @access public
381
- * @return string
382
- */
383
- public function custom_permalinks_term_link( $permalink, $term ) {
384
- $table = get_option( 'custom_permalink_table' );
385
- if ( is_object( $term ) ) {
386
- $term = $term->term_id;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
  }
388
 
389
- $custom_permalink = $this->custom_permalinks_permalink_for_term( $term );
390
- if ( $custom_permalink ) {
391
- $taxonomy = get_term( $term );
392
- if ( isset( $taxonomy ) && isset( $taxonomy->term_taxonomy_id ) ) {
393
- $term_type = 'category';
394
- if ( isset( $taxonomy->taxonomy ) ) {
395
- $term_type = $taxonomy->taxonomy;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
396
  }
397
- $language_code = apply_filters( 'wpml_element_language_code', null, array( 'element_id' => $taxonomy->term_taxonomy_id, 'element_type' => $term_type ) );
398
- return apply_filters( 'wpml_permalink', trailingslashit( home_url() ) . $custom_permalink, $language_code );
399
- } else {
400
- return apply_filters( 'wpml_permalink', trailingslashit( home_url() ) . $custom_permalink );
401
- }
402
- }
403
 
404
- return $permalink;
405
- }
406
-
407
- /**
408
- * Get original permalink for post
409
- *
410
- * @access public
411
- * @return string
412
- */
413
- public function custom_permalinks_original_post_link( $post_id ) {
414
- remove_filter( 'post_link', array( $this, 'custom_permalinks_post_link' ), 10, 3 );
415
- remove_filter( 'post_type_link', array( $this, 'custom_permalinks_post_link' ), 10, 2 );
416
-
417
- require_once ABSPATH . '/wp-admin/includes/post.php';
418
- list( $permalink, $post_name ) = get_sample_permalink( $post_id );
419
- $permalink = str_replace( array( '%pagename%','%postname%' ), $post_name, $permalink );
420
- $permalink = ltrim( str_replace( home_url(), '', $permalink ), '/' );
421
-
422
- add_filter( 'post_link', array( $this, 'custom_permalinks_post_link' ), 10, 3 );
423
- add_filter( 'post_type_link', array( $this, 'custom_permalinks_post_link' ), 10, 2 );
424
-
425
- return $permalink;
426
- }
427
-
428
- /**
429
- * Get original permalink for page
430
- *
431
- * @access public
432
- * @return string
433
- */
434
- public function custom_permalinks_original_page_link( $post_id ) {
435
- remove_filter( 'page_link', array( $this, 'custom_permalinks_page_link' ), 10, 2 );
436
- remove_filter( 'user_trailingslashit', array( $this, 'custom_permalinks_trailingslash' ), 10, 2 );
437
-
438
- require_once ABSPATH . '/wp-admin/includes/post.php';
439
- list( $permalink, $post_name ) = get_sample_permalink( $post_id );
440
- $permalink = str_replace( array( '%pagename%','%postname%' ), $post_name, $permalink );
441
- $permalink = ltrim( str_replace( home_url(), '', $permalink ), '/' );
442
-
443
- add_filter( 'user_trailingslashit', array( $this, 'custom_permalinks_trailingslash' ), 10, 2 );
444
- add_filter( 'page_link', array( $this, 'custom_permalinks_page_link' ), 10, 2 );
445
- return $permalink;
446
- }
447
-
448
- /**
449
- * Get original permalink for tag
450
- *
451
- * @access public
452
- * @return string
453
- */
454
- public function custom_permalinks_original_tag_link( $tag_id ) {
455
- remove_filter( 'tag_link', array( $this, 'custom_permalinks_term_link' ), 10, 2 );
456
- remove_filter( 'user_trailingslashit', array( $this, 'custom_permalinks_trailingslash' ), 10, 2 );
457
- $originalPermalink = ltrim( str_replace( home_url(), '', get_tag_link( $tag_id ) ), '/' );
458
- add_filter( 'user_trailingslashit', array( $this, 'custom_permalinks_trailingslash' ), 10, 2 );
459
- add_filter( 'tag_link', array( $this, 'custom_permalinks_term_link' ), 10, 2 );
460
- return $originalPermalink;
461
- }
462
-
463
- /**
464
- * Get original permalink for category
465
- *
466
- * @access public
467
- * @return string
468
- */
469
- public function custom_permalinks_original_category_link( $category_id ) {
470
- remove_filter( 'category_link', array( $this, 'custom_permalinks_term_link' ), 10, 2 );
471
- remove_filter( 'user_trailingslashit', array( $this, 'custom_permalinks_trailingslash' ), 10, 2 );
472
- $originalPermalink = ltrim( str_replace( home_url(), '', get_category_link( $category_id ) ), '/' );
473
- add_filter( 'user_trailingslashit', array( $this, 'custom_permalinks_trailingslash' ), 10, 2 );
474
- add_filter( 'category_link', array( $this, 'custom_permalinks_term_link' ), 10, 2 );
475
- return $originalPermalink;
476
- }
477
-
478
- /**
479
- * Filter to handle trailing slashes correctly
480
- *
481
- * @access public
482
- * @return string
483
- */
484
- public function custom_permalinks_trailingslash( $string, $type ) {
485
- global $_CPRegisteredURL;
486
-
487
- remove_filter( 'user_trailingslashit', array( $this, 'custom_permalinks_trailingslash' ), 10, 2 );
488
- $url = parse_url( get_bloginfo( 'url' ) );
489
- $request = ltrim( isset( $url['path'] ) ? substr( $string, strlen( $url['path'] ) ) : $string, '/' );
490
- add_filter( 'user_trailingslashit', array( $this, 'custom_permalinks_trailingslash' ), 10, 2 );
491
-
492
- if ( ! trim( $request ) ) {
493
- return $string;
494
  }
495
 
496
- if ( trim( $_CPRegisteredURL, '/' ) == trim( $request, '/' ) ) {
497
- if ( isset( $url['path'] ) ) {
498
- return ( $string{0} == '/' ? '/' : '' ) . trailingslashit( $url['path'] ) . $_CPRegisteredURL;
499
- } else {
500
- return ( $string{0} == '/' ? '/' : '' ) . $_CPRegisteredURL;
501
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
502
  }
503
- return $string;
504
- }
505
-
506
- /**
507
- * Get permalink for term
508
- *
509
- * @access public
510
- * @return boolean
511
- */
512
- public function custom_permalinks_permalink_for_term( $id ) {
513
- $table = get_option( 'custom_permalink_table' );
514
- if ( $table ) {
515
- foreach ( $table as $link => $info ) {
516
- if ( $info['id'] == $id ) {
517
- return $link;
 
 
518
  }
519
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
520
  }
521
- return false;
522
- }
523
  }
1
  <?php
2
  /**
3
+ * @package CustomPermalinks
4
  */
5
 
6
+ class Custom_Permalinks_Frontend
7
+ {
8
+
9
+ /*
10
+ * The query string, if any, via which the page is accessed otherwise empty.
11
+ */
12
+ private $query_string_uri = '';
13
+
14
+ /*
15
+ * The URI which is given in order to access this page. Default empty.
16
+ */
17
+ private $request_uri = '';
18
+
19
+ /**
20
+ * Initialize WordPress Hooks.
21
+ *
22
+ * @since 1.2.0
23
+ * @access public
24
+ */
25
+ public function init()
26
+ {
27
+ if ( isset( $_SERVER['QUERY_STRING'] ) ) {
28
+ $this->query_string_uri = $_SERVER['QUERY_STRING'];
29
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
+ if ( isset( $_SERVER['REQUEST_URI'] ) ) {
32
+ $this->request_uri = $_SERVER['REQUEST_URI'];
33
+ }
34
 
35
+ add_action( 'template_redirect', array( $this, 'make_redirect' ), 5 );
36
 
37
+ add_filter( 'request', array( $this, 'parse_request' ) );
38
+ add_filter( 'post_link', array( $this, 'custom_post_link' ), 10, 2 );
39
+ add_filter( 'post_type_link', array( $this, 'custom_post_link' ), 10, 2 );
40
+ add_filter( 'page_link', array( $this, 'custom_page_link' ), 10, 2 );
41
+ add_filter( 'term_link', array( $this, 'custom_term_link' ), 10, 2 );
42
+ add_filter( 'user_trailingslashit', array( $this, 'custom_trailingslash' ) );
43
+
44
+ // WPSEO Filters
45
+ add_filter( 'wpseo_canonical',
46
+ array( $this, 'fix_canonical_double_slash' ), 20, 1
47
+ );
48
  }
49
 
50
+ /**
51
+ * Replace double slash `//` with single slash `/`.
52
+ *
53
+ * @since 1.6.0
54
+ * @access public
55
+ *
56
+ * @param string $permalink URL in which `//` needs to be replaced with `/`.
57
+ *
58
+ * @return string URL with single slash.
59
+ */
60
+ public function remove_double_slash( $permalink = '' )
61
+ {
62
+ $protocol = '';
63
+ if ( 0 === strpos( $permalink, 'http://' )
64
+ || 0 === strpos( $permalink, 'https://' )
65
+ ) {
66
+ $split_protocol = explode( '://', $permalink );
67
+ if ( 1 < count( $split_protocol ) ) {
68
+ $protocol = $split_protocol[0] . '://';
69
+ $permalink = str_replace( $protocol, '', $permalink );
70
+ }
71
+ }
72
+
73
+ $permalink = str_replace( '//', '/', $permalink );
74
+ $permalink = $protocol . $permalink;
75
+
76
+ return $permalink;
77
  }
78
+
79
+ /**
80
+ * Use `wpml_permalink` to add language information to permalinks and
81
+ * resolve language switcher issue if found.
82
+ *
83
+ * @since 1.6.0
84
+ * @access public
85
+ *
86
+ * @param string $permalink Custom Permalink.
87
+ * @param string $language_code The language to convert the url into.
88
+ *
89
+ * @return string permalink with language information.
90
+ */
91
+ public function wpml_permalink_filter( $permalink = '', $language_code )
92
+ {
93
+ $custom_permalink = $permalink;
94
+ $trailing_permalink = trailingslashit( home_url() ) . $custom_permalink;
95
+ if ( $language_code ) {
96
+ $permalink = apply_filters( 'wpml_permalink', $trailing_permalink,
97
+ $language_code
98
+ );
99
+ $site_url = site_url();
100
+ $wpml_href = str_replace( $site_url, '', $permalink );
101
+ if ( 0 === strpos( $wpml_href, '//' ) ) {
102
+ if ( 0 !== strpos( $wpml_href, '//' . $language_code . '/' ) ) {
103
+ $permalink = $site_url . '/' . $language_code . '/' . $custom_permalink;
104
+ }
105
+ }
106
+ } else {
107
+ $permalink = apply_filters( 'wpml_permalink', $trailing_permalink );
108
+ }
109
+
110
+ return $permalink;
111
  }
112
 
113
+ /**
114
+ * Filter to rewrite the query if we have a matching post.
115
+ *
116
+ * @since 0.1.0
117
+ * @access public
118
+ *
119
+ * @param string $query Requested URL.
120
+ *
121
+ * @return string the URL which has to be parsed.
122
+ */
123
+ public function parse_request( $query )
124
+ {
125
+ global $wpdb;
126
+ global $_CPRegisteredURL;
127
+
128
+ /*
129
+ * First, search for a matching custom permalink, and if found
130
+ * generate the corresponding original URL
131
+ */
132
+ $original_url = NULL;
133
+
134
+ // Get request URI, strip parameters and /'s
135
+ $url = parse_url( get_bloginfo( 'url' ) );
136
+ $url = isset( $url['path'] ) ? $url['path'] : '';
137
+ $request = ltrim( substr( $this->request_uri, strlen( $url ) ), '/' );
138
+ $pos = strpos( $request, '?' );
139
+ if ( $pos ) {
140
+ $request = substr( $request, 0, $pos );
141
+ }
142
 
143
+ if ( ! $request ) {
144
+ return $query;
 
 
 
145
  }
146
+
147
+ $ignore = apply_filters( 'custom_permalinks_request_ignore', $request );
148
+
149
+ if ( '__true' === $ignore ) {
150
+ return $query;
 
 
 
 
 
 
 
151
  }
 
 
152
 
153
+ if ( defined( 'POLYLANG_VERSION' ) ) {
154
+ $cp_file_path = CUSTOM_PERMALINKS_PATH;
155
+ $cp_file_path .= 'frontend/class-custom-permalinks-form.php';
156
+ include_once $cp_file_path;
157
+
158
+ $cp_form = new Custom_Permalinks_Form();
159
+ $request = $cp_form->check_conflicts( $request );
160
+ }
161
+ $request_no_slash = preg_replace( '@/+@','/', trim( $request, '/' ) );
162
+
163
+ $sql = $wpdb->prepare( "SELECT p.ID, pm.meta_value, p.post_type, p.post_status " .
164
+ " FROM $wpdb->posts AS p INNER JOIN $wpdb->postmeta AS pm ON (pm.post_id = p.ID) " .
165
+ " WHERE pm.meta_key = 'custom_permalink' " .
166
+ " AND (pm.meta_value = '%s' OR pm.meta_value = '%s') " .
167
+ " AND p.post_status != 'trash' AND p.post_type != 'nav_menu_item' " .
168
+ " ORDER BY FIELD(post_status,'publish','private','pending','draft','auto-draft','inherit')," .
169
+ " FIELD(post_type,'post','page') LIMIT 1", $request_no_slash, $request_no_slash . "/" );
170
+
171
+ $posts = $wpdb->get_results( $sql );
172
+
173
+ $remove_like_query = apply_filters( 'cp_remove_like_query', '__true' );
174
+ if ( ! $posts && '__true' === $remove_like_query ) {
175
+ $sql = $wpdb->prepare( "SELECT p.ID, pm.meta_value, p.post_type, p.post_status FROM $wpdb->posts AS p " .
176
+ " LEFT JOIN $wpdb->postmeta AS pm ON (p.ID = pm.post_id) WHERE " .
177
+ " meta_key = 'custom_permalink' AND meta_value != '' AND " .
178
+ " ( LOWER(meta_value) = LEFT(LOWER('%s'), LENGTH(meta_value)) OR " .
179
+ " LOWER(meta_value) = LEFT(LOWER('%s'), LENGTH(meta_value)) ) " .
180
+ " AND post_status != 'trash' AND post_type != 'nav_menu_item'" .
181
+ " ORDER BY LENGTH(meta_value) DESC, " .
182
+ " FIELD(post_status,'publish','private','pending','draft','auto-draft','inherit')," .
183
+ " FIELD(post_type,'post','page'), p.ID ASC LIMIT 1",
184
+ $request_no_slash, $request_no_slash . "/" );
185
+
186
+ $posts = $wpdb->get_results( $sql );
187
  }
 
 
188
 
189
+ if ( $posts ) {
190
+ /*
191
+ * A post matches our request. Preserve this url for later
192
+ * if it's the same as the permalink (no extra stuff).
193
+ */
194
+ if ( $request_no_slash == trim( $posts[0]->meta_value, '/' ) ) {
195
+ $_CPRegisteredURL = $request;
196
+ }
197
+
198
+ if ( 'draft' == $posts[0]->post_status ) {
199
+ if ( 'page' == $posts[0]->post_type ) {
200
+ $original_url = '?page_id=' . $posts[0]->ID;
201
+ } else {
202
+ $original_url = '?post_type=' . $posts[0]->post_type . '&p=' . $posts[0]->ID;
203
+ }
204
+ } else {
205
+ $post_meta = trim( strtolower( $posts[0]->meta_value ), '/' );
206
+ if ( $posts[0]->post_type == 'page' ) {
207
+ $get_original_url = $this->original_page_link( $posts[0]->ID );
208
+ $original_url = preg_replace( '@/+@', '/',
209
+ str_replace( $post_meta, $get_original_url,
210
+ strtolower( $request_no_slash )
211
+ )
212
+ );
213
+ } else {
214
+ $get_original_url = $this->original_post_link( $posts[0]->ID );
215
+ $original_url = preg_replace( '@/+@', '/',
216
+ str_replace( $post_meta, $get_original_url,
217
+ strtolower( $request_no_slash )
218
+ )
219
+ );
220
+ }
221
+ }
 
 
222
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
 
224
+ if ( NULL === $original_url ) {
225
+ // See if any terms have a matching permalink
226
+ $table = get_option( 'custom_permalink_table' );
227
+ if ( ! $table ) {
228
+ return $query;
229
+ }
230
+
231
+ foreach ( array_keys( $table ) as $permalink ) {
232
+ if ( $permalink === substr( $request_no_slash, 0, strlen( $permalink ) )
233
+ || $permalink === substr( $request_no_slash . '/', 0, strlen( $permalink ) )
234
+ ) {
235
+ $term = $table[$permalink];
236
+
237
+ /*
238
+ * Preserve this url for later if it's the same as the
239
+ * permalink (no extra stuff)
240
+ */
241
+ if ( $request_no_slash === trim( $permalink, '/' ) ) {
242
+ $_CPRegisteredURL = $request;
243
+ }
244
+
245
+ $term_link = $this->original_term_link( $term['id'] );
246
+ $original_url = str_replace( trim( $permalink, '/' ),
247
+ $term_link, trim( $request, '/' )
248
+ );
249
+ }
250
+ }
251
+ }
252
 
253
+ if ( NULL !== $original_url ) {
254
+ $original_url = str_replace( '//', '/', $original_url );
255
+
256
+ $pos = strpos( $this->request_uri, '?' );
257
+ if ( false !== $pos ) {
258
+ $query_vars = substr( $this->request_uri, $pos + 1 );
259
+ $original_url .= ( strpos( $original_url, '?' ) === false ? '?' : '&' ) . $query_vars;
260
+ }
261
+
262
+ /*
263
+ * Now we have the original URL, run this back through WP->parse_request,
264
+ * in order to parse parameters properly.
265
+ * We set $_SERVER variables to fool the function.
266
+ */
267
+ $_SERVER['REQUEST_URI'] = '/' . ltrim( $original_url, '/' );
268
+ $path_info = apply_filters( 'custom_permalinks_path_info', '__false' );
269
+ if ( '__false' !== $path_info ) {
270
+ $_SERVER['PATH_INFO'] = '/' . ltrim( $original_url, '/' );
271
+ }
272
+
273
+ $_SERVER['QUERY_STRING'] = '';
274
+ $pos = strpos( $original_url, '?' );
275
+ if ( false !== $pos ) {
276
+ $_SERVER['QUERY_STRING'] = substr( $original_url, $pos + 1 );
277
+ }
278
+
279
+ parse_str( $_SERVER['QUERY_STRING'], $query_array );
280
+ $old_values = array();
281
+ if ( is_array( $query_array ) ) {
282
+ foreach ( $query_array as $key => $value ) {
283
+ $old_values[$key] = '';
284
+ if ( isset( $_REQUEST[$key] ) ) {
285
+ $old_values[$key] = $_REQUEST[$key];
286
+ }
287
+ $_REQUEST[$key] = $_GET[$key] = $value;
288
+ }
289
+ }
290
+
291
+ // Re-run the filter, now with original environment in place
292
+ remove_filter( 'request', array( $this, 'parse_request' ) );
293
+ global $wp;
294
+ if ( isset( $wp->matched_rule ) ) {
295
+ $wp->matched_rule = NULL;
296
+ }
297
+ $wp->parse_request();
298
+ $query = $wp->query_vars;
299
+ add_filter( 'request', array( $this, 'parse_request' ) );
300
+
301
+ // Restore values
302
+ $_SERVER['REQUEST_URI'] = $this->request_uri;
303
+ $_SERVER['QUERY_STRING'] = $this->query_string_uri;
304
+ foreach ( $old_values as $key => $value ) {
305
+ $_REQUEST[$key] = $value;
306
+ }
307
+ }
308
+
309
+ return $query;
310
  }
311
 
312
+ /**
313
+ * Action to redirect to the custom permalink.
314
+ *
315
+ * @since 0.1.0
316
+ * @access public
317
+ */
318
+ public function make_redirect()
319
+ {
320
+ global $wpdb;
321
+
322
+ $custom_permalink = '';
323
+ $original_permalink = '';
324
+
325
+ // Get request URI, strip parameters
326
+ $url = parse_url( get_bloginfo( 'url' ) );
327
+ $url = isset( $url['path'] ) ? $url['path'] : '';
328
+ $request = ltrim( substr( $this->request_uri, strlen( $url ) ), '/' );
329
+ $pos = strpos( $request, '?' );
330
+ if ( $pos ) {
331
+ $request = substr( $request, 0, $pos );
332
+ }
333
 
334
+ if ( defined( 'POLYLANG_VERSION' ) ) {
335
+ $cp_file_path = CUSTOM_PERMALINKS_PATH;
336
+ $cp_file_path .= 'frontend/class-custom-permalinks-form.php';
337
+ include_once $cp_file_path;
338
+
339
+ $cp_form = new Custom_Permalinks_Form();
340
+ $request = $cp_form->check_conflicts( $request );
341
+ }
342
+ $request_no_slash = preg_replace( '@/+@','/', trim( $request, '/' ) );
343
+
344
+ $sql = $wpdb->prepare( "SELECT p.ID, pm.meta_value, p.post_type, p.post_status " .
345
+ " FROM $wpdb->posts AS p INNER JOIN $wpdb->postmeta AS pm ON (pm.post_id = p.ID) " .
346
+ " WHERE pm.meta_key = 'custom_permalink' " .
347
+ " AND (pm.meta_value = '%s' OR pm.meta_value = '%s') " .
348
+ " AND p.post_status != 'trash' AND p.post_type != 'nav_menu_item' " .
349
+ " ORDER BY FIELD(post_status,'publish','private','draft','auto-draft','inherit')," .
350
+ " FIELD(post_type,'post','page') LIMIT 1", $request_no_slash, $request_no_slash . "/" );
351
+
352
+ $posts = $wpdb->get_results( $sql );
353
+
354
+ $remove_like_query = apply_filters( 'cp_remove_like_query', '__true' );
355
+ if ( ! $posts && '__false' !== $remove_like_query ) {
356
+ $sql = $wpdb->prepare( "SELECT p.ID, pm.meta_value, p.post_type, p.post_status FROM $wpdb->posts AS p " .
357
+ " LEFT JOIN $wpdb->postmeta AS pm ON (p.ID = pm.post_id) WHERE " .
358
+ " meta_key = 'custom_permalink' AND meta_value != '' AND " .
359
+ " ( LOWER(meta_value) = LEFT(LOWER('%s'), LENGTH(meta_value)) OR " .
360
+ " LOWER(meta_value) = LEFT(LOWER('%s'), LENGTH(meta_value)) ) " .
361
+ " AND post_status != 'trash' AND post_type != 'nav_menu_item'" .
362
+ " ORDER BY LENGTH(meta_value) DESC, " .
363
+ " FIELD(post_status,'publish','private','draft','auto-draft','inherit')," .
364
+ " FIELD(post_type,'post','page'), p.ID ASC LIMIT 1",
365
+ $request_no_slash, $request_no_slash . "/" );
366
+
367
+ $posts = $wpdb->get_results( $sql );
368
  }
369
+
370
+ if ( ! isset( $posts[0]->ID ) || ! isset( $posts[0]->meta_value )
371
+ || empty( $posts[0]->meta_value )
372
+ ) {
373
+ global $wp_query;
374
+
375
+ /*
376
+ * If the post/tag/category we're on has a custom permalink, get it
377
+ * and check against the request.
378
+ */
379
+ if ( ( is_single() || is_page() ) && ! empty( $wp_query->post ) ) {
380
+ $post = $wp_query->post;
381
+ $custom_permalink = get_post_meta( $post->ID,
382
+ 'custom_permalink', true
383
+ );
384
+ if ( 'page' === $post->post_type ) {
385
+ $original_permalink = $this->original_page_link( $post->ID );
386
+ } else {
387
+ $original_permalink = $this->original_post_link( $post->ID );
388
+ }
389
+ } elseif ( is_tag() || is_category() ) {
390
+ $the_term = $wp_query->get_queried_object();
391
+ $custom_permalink = $this->term_permalink( $the_term->term_id );
392
+ $original_permalink = $this->original_term_link( $the_term->term_id );
393
+ }
394
  } else {
395
+ $custom_permalink = $posts[0]->meta_value;
396
+ if ( 'page' === $posts[0]->post_type ) {
397
+ $original_permalink = $this->original_page_link( $posts[0]->ID );
398
+ } else {
399
+ $original_permalink = $this->original_post_link( $posts[0]->ID );
400
+ }
401
+ }
402
+
403
+ if ( $custom_permalink
404
+ && (
405
+ substr( $request, 0, strlen( $custom_permalink ) ) != $custom_permalink
406
+ || $request == $custom_permalink . '/'
407
+ )
408
+ ) {
409
+ // Request doesn't match permalink - redirect
410
+ $url = $custom_permalink;
411
+
412
+ if ( substr( $request, 0, strlen( $original_permalink ) ) == $original_permalink
413
+ && trim( $request, '/' ) != trim( $original_permalink, '/' )
414
+ ) {
415
+ // This is the original link; we can use this url to derive the new one
416
+ $url = preg_replace( '@//*@', '/', str_replace(
417
+ trim( $original_permalink, '/' ),
418
+ trim( $custom_permalink, '/' ), $request
419
+ ) );
420
+ $url = preg_replace( '@([^?]*)&@', '\1?', $url );
421
+ }
422
+
423
+ // Append any query compenent
424
+ $url .= strstr( $this->request_uri, '?' );
425
+
426
+ wp_safe_redirect( home_url() . '/' . $url, 301 );
427
+ exit(0);
428
  }
 
 
 
 
 
 
 
 
429
  }
430
 
431
+ /**
432
+ * Filter to replace the post permalink with the custom one.
433
+ *
434
+ * @access public
435
+ *
436
+ * @param string $permalink Default WordPress Permalink of Post.
437
+ * @param object $post Post Details.
438
+ *
439
+ * @return string customized Post Permalink.
440
+ */
441
+ public function custom_post_link( $permalink, $post )
442
+ {
443
+ $custom_permalink = get_post_meta( $post->ID, 'custom_permalink', true );
444
+ if ( $custom_permalink ) {
445
+ $post_type = 'post';
446
+ if ( isset( $post->post_type ) ) {
447
+ $post_type = $post->post_type;
448
+ }
449
+
450
+ $language_code = apply_filters( 'wpml_element_language_code', null,
451
+ array(
452
+ 'element_id' => $post->ID,
453
+ 'element_type' => $post_type
454
+ )
455
+ );
456
+
457
+ $permalink = $this->wpml_permalink_filter( $custom_permalink,
458
+ $language_code
459
+ );
460
+ } else {
461
+ if ( class_exists( 'SitePress' ) ) {
462
+ $wpml_lang_format = apply_filters( 'wpml_setting', 0,
463
+ 'language_negotiation_type'
464
+ );
465
+
466
+ if ( 1 === intval( $wpml_lang_format ) ) {
467
+ $get_original_url = $this->original_post_link( $post->ID );
468
+ $permalink = $this->remove_double_slash( $permalink );
469
+ if ( strlen( $get_original_url ) === strlen( $permalink ) ) {
470
+ $permalink = $get_original_url;
471
+ }
472
+ }
473
+ }
474
+ }
475
+
476
+ $permalink = $this->remove_double_slash( $permalink );
477
 
478
+ return $permalink;
479
+ }
480
 
481
+ /**
482
+ * Filter to replace the page permalink with the custom one.
483
+ *
484
+ * @access public
485
+ *
486
+ * @param string $permalink Default WordPress Permalink of Page.
487
+ * @param int $page Page ID.
488
+ *
489
+ * @return string customized Page Permalink.
490
+ */
491
+ public function custom_page_link( $permalink, $page )
492
+ {
493
+ $custom_permalink = get_post_meta( $page, 'custom_permalink', true );
494
+ if ( $custom_permalink ) {
495
+ $language_code = apply_filters( 'wpml_element_language_code', null,
496
+ array(
497
+ 'element_id' => $page,
498
+ 'element_type' => 'page'
499
+ )
500
+ );
501
+
502
+ $permalink = $this->wpml_permalink_filter( $custom_permalink,
503
+ $language_code
504
+ );
505
+ } else {
506
+ if ( class_exists( 'SitePress' ) ) {
507
+ $wpml_lang_format = apply_filters( 'wpml_setting', 0,
508
+ 'language_negotiation_type'
509
+ );
510
+
511
+ if ( 1 === intval( $wpml_lang_format ) ) {
512
+ $get_original_url = $this->original_page_link( $page );
513
+ $permalink = $this->remove_double_slash( $permalink );
514
+ if ( strlen( $get_original_url ) === strlen( $permalink ) ) {
515
+ $permalink = $get_original_url;
516
+ }
517
+ }
518
+ }
519
+ }
520
 
521
+ $permalink = $this->remove_double_slash( $permalink );
 
522
 
523
+ return $permalink;
 
524
  }
525
+
526
+ /**
527
+ * Filter to replace the term permalink with the custom one.
528
+ *
529
+ * @access public
530
+ *
531
+ * @param string $permalink Term link URL.
532
+ * @param object $term Term object.
533
+ *
534
+ * @return string customized Term Permalink.
535
+ */
536
+ public function custom_term_link( $permalink, $term )
537
+ {
538
+ if ( isset( $term ) ) {
539
+ if ( isset( $term->term_id ) ) {
540
+ $custom_permalink = $this->term_permalink( $term->term_id );
541
+ }
542
+
543
+ if ( $custom_permalink ) {
544
+ $language_code = NULL;
545
+ if ( isset( $term->term_taxonomy_id ) ) {
546
+ $term_type = 'category';
547
+ if ( isset( $term->taxonomy ) ) {
548
+ $term_type = $term->taxonomy;
549
+ }
550
+
551
+ $language_code = apply_filters( 'wpml_element_language_code',
552
+ null, array(
553
+ 'element_id' => $term->term_taxonomy_id,
554
+ 'element_type' => $term_type
555
+ )
556
+ );
557
+ }
558
+
559
+ $permalink = $this->wpml_permalink_filter( $custom_permalink,
560
+ $language_code
561
+ );
562
+ } elseif ( isset( $term->term_id ) ) {
563
+ if ( class_exists( 'SitePress' ) ) {
564
+ $wpml_lang_format = apply_filters( 'wpml_setting', 0,
565
+ 'language_negotiation_type'
566
+ );
567
+
568
+ if ( 1 === intval( $wpml_lang_format ) ) {
569
+ $get_original_url = $this->original_term_link(
570
+ $term->term_id
571
+ );
572
+ $permalink = $this->remove_double_slash( $permalink );
573
+ if ( strlen( $get_original_url ) === strlen( $permalink ) ) {
574
+ $permalink = $get_original_url;
575
+ }
576
+ }
577
+ }
578
+ }
579
+ }
580
+
581
+ $permalink = $this->remove_double_slash( $permalink );
582
+
583
+ return $permalink;
584
  }
585
 
586
+ /**
587
+ * Remove the post_link and user_trailingslashit filter to get the original
588
+ * permalink of the default and custom post type and apply right after that.
589
+ *
590
+ * @access public
591
+ *
592
+ * @param int $post_id Post ID.
593
+ *
594
+ * @return string Original Permalink for Posts.
595
+ */
596
+ public function original_post_link( $post_id )
597
+ {
598
+ remove_filter( 'post_link', array( $this, 'custom_post_link' ), 10, 3 );
599
+ remove_filter( 'post_type_link', array( $this, 'custom_post_link' ), 10, 2 );
600
+
601
+ $post_file_path = ABSPATH . '/wp-admin/includes/post.php';
602
+ require_once $post_file_path;
603
+
604
+ list( $permalink, $post_name ) = get_sample_permalink( $post_id );
605
+ $permalink = str_replace( array( '%pagename%','%postname%' ), $post_name,
606
+ $permalink
607
+ );
608
+ $permalink = ltrim( str_replace( home_url(), '', $permalink ), '/' );
609
+
610
+ add_filter( 'post_link', array( $this, 'custom_post_link' ), 10, 3 );
611
+ add_filter( 'post_type_link', array( $this, 'custom_post_link' ), 10, 2 );
612
+
613
+ return $permalink;
614
  }
615
 
616
+ /**
617
+ * Remove the page_link and user_trailingslashit filter to get the original
618
+ * permalink of the page and apply right after that.
619
+ *
620
+ * @access public
621
+ *
622
+ * @param int $post_id Page ID.
623
+ *
624
+ * @return string Original Permalink for the Page.
625
+ */
626
+ public function original_page_link( $post_id )
627
+ {
628
+ remove_filter( 'page_link', array( $this, 'custom_page_link' ), 10, 2 );
629
+ remove_filter( 'user_trailingslashit',
630
+ array( $this, 'custom_trailingslash' )
631
+ );
632
+
633
+ $post_file_path = ABSPATH . '/wp-admin/includes/post.php';
634
+ require_once $post_file_path;
635
+
636
+ list( $permalink, $post_name ) = get_sample_permalink( $post_id );
637
+ $permalink = str_replace( array( '%pagename%','%postname%' ), $post_name,
638
+ $permalink
639
+ );
640
+ $permalink = ltrim( str_replace( home_url(), '', $permalink ), '/' );
641
+
642
+ add_filter( 'user_trailingslashit', array( $this, 'custom_trailingslash' ) );
643
+ add_filter( 'page_link', array( $this, 'custom_page_link' ), 10, 2 );
644
+
645
+ return $permalink;
646
  }
647
 
648
+ /**
649
+ * Remove the term_link and user_trailingslashit filter to get the original
650
+ * permalink of the Term and apply right after that.
651
+ *
652
+ * @since 1.6.0
653
+ * @access public
654
+ *
655
+ * @param int $term_id Term ID.
656
+ *
657
+ * @return string Original Permalink for Posts.
658
+ */
659
+ public function original_term_link( $term_id )
660
+ {
661
+ remove_filter( 'term_link', array( $this, 'custom_term_link' ), 10, 2 );
662
+ remove_filter( 'user_trailingslashit',
663
+ array( $this, 'custom_trailingslash' )
664
+ );
665
+
666
+ $term = get_term( $term_id );
667
+ $term_link = get_term_link( $term );
668
+
669
+ add_filter( 'user_trailingslashit', array( $this, 'custom_trailingslash' ) );
670
+ add_filter( 'term_link', array( $this, 'custom_term_link' ), 10, 2 );
671
+
672
+ if ( is_wp_error( $term_link ) ) {
673
+ return '';
674
  }
 
 
 
 
 
 
675
 
676
+ $original_permalink = ltrim( str_replace( home_url(), '', $term_link ), '/' );
677
+
678
+ return $original_permalink;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
679
  }
680
 
681
+ /**
682
+ * Filter to handle trailing slashes correctly.
683
+ *
684
+ * @access public
685
+ *
686
+ * @param string $url_string URL with or without a trailing slash.
687
+ *
688
+ * @return string Adds/removes a trailing slash based on the permalink structure.
689
+ */
690
+ public function custom_trailingslash( $url_string )
691
+ {
692
+ global $_CPRegisteredURL;
693
+
694
+ remove_filter( 'user_trailingslashit',
695
+ array( $this, 'custom_trailingslash' )
696
+ );
697
+
698
+ $trailingslash_string = $url_string;
699
+ $url = parse_url( get_bloginfo( 'url' ) );
700
+
701
+ if ( isset( $url['path'] ) ) {
702
+ $request = substr( $url_string, strlen( $url['path'] ) );
703
+ } else {
704
+ $request = $url_string;
705
+ }
706
+
707
+ $request = ltrim( $request, '/' );
708
+
709
+ add_filter( 'user_trailingslashit', array( $this, 'custom_trailingslash' ) );
710
+
711
+ if ( trim( $request ) ) {
712
+ if ( trim( $_CPRegisteredURL, '/' ) == trim( $request, '/' ) ) {
713
+ if ( '/' === $url_string[0] ) {
714
+ $trailingslash_string = '/';
715
+ } else {
716
+ $trailingslash_string = '';
717
+ }
718
+
719
+ if ( isset( $url['path'] ) ) {
720
+ $trailingslash_string .= trailingslashit( $url['path'] );
721
+ }
722
+
723
+ $trailingslash_string .= $_CPRegisteredURL;
724
+ }
725
+ }
726
+
727
+ return $trailingslash_string;
728
  }
729
+
730
+ /**
731
+ * Get permalink for term.
732
+ *
733
+ * @access public
734
+ *
735
+ * @return bool Term link.
736
+ */
737
+ public function term_permalink( $term_id )
738
+ {
739
+ $table = get_option( 'custom_permalink_table' );
740
+ if ( $table ) {
741
+ foreach ( $table as $link => $info ) {
742
+ if ( $info['id'] == $term_id ) {
743
+ return $link;
744
+ }
745
+ }
746
  }
747
+
748
+ return false;
749
+ }
750
+
751
+ /**
752
+ * Fix double slash issue with canonical of Yoast SEO specially with WPML.
753
+ *
754
+ * @since 1.6.0
755
+ * @access public
756
+ *
757
+ * @param string $canonical The canonical.
758
+ *
759
+ * @return string the canonical after removing double slash if exist.
760
+ */
761
+ public function fix_canonical_double_slash( $canonical )
762
+ {
763
+ $canonical = $this->remove_double_slash( $canonical );
764
+
765
+ return $canonical;
766
  }
 
 
767
  }
frontend/index.php CHANGED
@@ -1,4 +1,4 @@
1
  <?php
2
  /**
3
  * Silence is golden
4
- */
1
  <?php
2
  /**
3
  * Silence is golden
4
+ */
frontend/js/script-form.js DELETED
@@ -1,54 +0,0 @@
1
- var getHomeURL = document.getElementById( 'custom_permalinks_home_url' ),
2
- getPermalink = document.getElementById( 'custom_permalink' ),
3
- checkYoastSEO = document.getElementById( 'wpseo_meta' );
4
-
5
- function changeSEOLinkOnBlur () {
6
- var snippetCiteBase = document.getElementById( 'snippet_citeBase' );
7
- if ( snippetCiteBase && getHomeURL && getHomeURL.value != "" && getPermalink && getPermalink.value ) {
8
- var i = 0;
9
- var urlChanged = setInterval( function() {
10
- i++;
11
- snippetCiteBase.innerHTML = getHomeURL.value + '/' + getPermalink.value;
12
- if (i === 5) {
13
- clearInterval(urlChanged);
14
- }
15
- }, 1000);
16
- }
17
- }
18
-
19
- function changeSEOLink () {
20
- var snippetCiteBase = document.getElementById( 'snippet_citeBase' );
21
- if ( snippetCiteBase && getHomeURL && getHomeURL.value != "" && getPermalink && getPermalink.value ) {
22
- var i = 0;
23
- var urlChanged = setInterval( function() {
24
- i++;
25
- snippetCiteBase.innerHTML = getHomeURL.value + '/' + getPermalink.value;
26
- if (i === 5) {
27
- clearInterval(urlChanged);
28
- }
29
- }, 1000);
30
- var snippetEditorTitle = document.getElementById( 'snippet-editor-title' ),
31
- snippetEditorSlug = document.getElementById( 'snippet-editor-slug' ),
32
- snippetEditorDesc = document.getElementById( 'snippet-editor-meta-description' ),
33
- snippetCite = document.getElementById( 'snippet_cite' );
34
- if ( snippetEditorTitle ) {
35
- snippetEditorTitle.addEventListener("blur", changeSEOLinkOnBlur, false);
36
- }
37
- if ( snippetEditorSlug ) {
38
- snippetEditorSlug.addEventListener("blur", changeSEOLinkOnBlur, false);
39
- }
40
- if ( snippetEditorDesc ) {
41
- snippetEditorDesc.addEventListener("blur", changeSEOLinkOnBlur, false);
42
- }
43
- if ( snippetCite ) {
44
- snippetCite.style.display = 'none';
45
- }
46
- }
47
- }
48
-
49
- if ( checkYoastSEO ) {
50
- window.addEventListener("load", changeSEOLink, false);
51
- }
52
- if ( document.querySelector("#custom-permalinks-edit-box .inside").innerHTML.trim() === "" ) {
53
- document.getElementById("custom-permalinks-edit-box").style.display = "none";
54
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/js/script-form.min.js CHANGED
@@ -1 +1 @@
1
- var getHomeURL=document.getElementById("custom_permalinks_home_url"),getPermalink=document.getElementById("custom_permalink"),checkYoastSEO=document.getElementById("wpseo_meta");function changeSEOLinkOnBlur(){var e=document.getElementById("snippet_citeBase");if(e&&getHomeURL&&""!=getHomeURL.value&&getPermalink&&getPermalink.value)var t=0,n=setInterval(function(){t++,e.innerHTML=getHomeURL.value+"/"+getPermalink.value,5===t&&clearInterval(n)},1e3)}function changeSEOLink(){var e=document.getElementById("snippet_citeBase");if(e&&getHomeURL&&""!=getHomeURL.value&&getPermalink&&getPermalink.value){var t=0,n=setInterval(function(){t++,e.innerHTML=getHomeURL.value+"/"+getPermalink.value,5===t&&clearInterval(n)},1e3),i=document.getElementById("snippet-editor-title"),l=document.getElementById("snippet-editor-slug"),a=document.getElementById("snippet-editor-meta-description"),m=document.getElementById("snippet_cite");i&&i.addEventListener("blur",changeSEOLinkOnBlur,!1),l&&l.addEventListener("blur",changeSEOLinkOnBlur,!1),a&&a.addEventListener("blur",changeSEOLinkOnBlur,!1),m&&(m.style.display="none")}}checkYoastSEO&&window.addEventListener("load",changeSEOLink,!1),""===document.querySelector("#custom-permalinks-edit-box .inside").innerHTML.trim()&&(document.getElementById("custom-permalinks-edit-box").style.display="none");
1
+ var getHomeURL=document.getElementById("custom_permalinks_home_url"),getPermalink=document.getElementById("custom_permalink"),editPost="",isSaving="",lastIsSaving=!1;function focusPermalinkField(){"use strict";var e=document.getElementById("custom-permalinks-post-slug");e&&(e.style.color="#000")}function blurPermalinkField(){"use strict";var e=document.getElementById("custom-permalinks-post-slug"),t=document.getElementById("original-permalink");e&&(getPermalink.value=e.value,""!==e.value&&e.value!==t.value||(e.value=t.value,e.style.color="#ddd"))}function updateMetaBox(){"use strict";var e,t,a;editPost&&((e=document.getElementsByClassName("edit-post-post-link__preview-label"))&&e[0]&&e[0].parentNode.classList.add("cp-permalink-hidden"),(isSaving=editPost.isSavingMetaBoxes())===lastIsSaving||isSaving||(t=wp.data.select("core/editor").getEditedPostAttribute("id"),a=new XMLHttpRequest,lastIsSaving=isSaving,a.onreadystatechange=function(){var e,t,n;4===a.readyState&&200===a.status&&(e=JSON.parse(a.responseText),t=document.getElementById("custom-permalinks-add"),getPermalink.value=e.custom_permalink,""===e.custom_permalink&&(e.custom_permalink=e.original_permalink),n=e.preview_permalink?getHomeURL.value+e.preview_permalink:getHomeURL.value+e.custom_permalink,document.getElementById("custom-permalinks-post-slug").value=e.custom_permalink,document.getElementById("original-permalink").value=e.original_permalink,document.querySelector("#view-post-btn a")&&(document.querySelector("#view-post-btn a").href=n),document.querySelector("a.editor-post-preview")&&(document.querySelector("a.editor-post-preview").href=n),t&&"add"===t.value&&(document.getElementById("custom-permalinks-edit-box").style.display=""),document.querySelector(".components-notice__content a")&&(document.querySelector(".components-notice__content a").href="/"+e.custom_permalink))},a.open("GET",getHomeURL.value+"/wp-json/custom-permalinks/v1/get-permalink/"+t,!0),a.setRequestHeader("Cache-Control","private, max-age=0, no-cache"),a.send()),lastIsSaving=isSaving)}function hideDefaultPermalink(){"use strict";var e=document.getElementsByClassName("edit-post-post-link__preview-label");e&&e[0]&&e[0].parentNode.classList.add("cp-permalink-hidden")}function permalinkContentLoaded(){"use strict";var e=document.getElementsByClassName("edit-post-post-link__preview-label"),t=document.getElementById("custom-permalinks-edit-box"),n=document.getElementById("custom-permalinks-post-slug");if(n&&(n.addEventListener("focus",focusPermalinkField),n.addEventListener("blur",blurPermalinkField)),""===document.querySelector("#custom-permalinks-edit-box .inside").innerHTML.trim()&&(t.style.display="none"),wp.data){var a=document.getElementById("custom-permalinks-add"),s=document.querySelectorAll(".edit-post-sidebar .components-panel__header"),i=0,o=s.length;if(a&&"add"===a.value&&(t.style.display="none"),editPost=wp.data.select("core/edit-post"),wp.data.subscribe(updateMetaBox),e&&e[0]&&e[0].parentNode.classList.add("cp-permalink-hidden"),t.classList.contains("closed")&&t.classList.remove("closed"),s&&0<o)for(;i<o;)s[i].addEventListener("click",hideDefaultPermalink),i+=1}}document.addEventListener("DOMContentLoaded",permalinkContentLoaded);
index.php CHANGED
@@ -1,4 +1,4 @@
1
  <?php
2
  /**
3
  * Silence is golden
4
- */
1
  <?php
2
  /**
3
  * Silence is golden
4
+ */
license.txt CHANGED
@@ -671,4 +671,4 @@ into proprietary programs. If your program is a subroutine library, you
671
  may consider it more useful to permit linking proprietary applications with
672
  the library. If this is what you want to do, use the GNU Lesser General
673
  Public License instead of this License. But first, please read
674
- <http://www.gnu.org/philosophy/why-not-lgpl.html>.
671
  may consider it more useful to permit linking proprietary applications with
672
  the library. If this is what you want to do, use the GNU Lesser General
673
  Public License instead of this License. But first, please read
674
+ <http://www.gnu.org/philosophy/why-not-lgpl.html>.
readme.txt CHANGED
@@ -1,10 +1,9 @@
1
  === Custom Permalinks ===
2
  Contributors: sasiddiqui, michaeltyson
3
- Donate link: https://www.paypal.me/yasglobal
4
  Tags: permalink, url, link, address, custom, redirect, custom post type, GDPR, GDPR Compliant
5
  Requires at least: 2.6
6
- Tested up to: 5.2
7
- Stable tag: 1.5.1
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl.html
10
 
@@ -12,63 +11,92 @@ Set custom permalinks on a per-post, per-tag or per-category basis.
12
 
13
  == Description ==
14
 
15
- Lay out your site the way *you* want it. Set the URL of any post, page, tag or category to anything you want.
16
- Old permalinks will redirect properly to the new address. Custom Permalinks gives you ultimate control
17
- over your site structure.
18
 
19
- Be warned: *This plugin is not a replacement for WordPress's built-in permalink system*. Check your WordPress
20
- administration's "Permalinks" settings page first, to make sure that this doesn't already meet your needs.
21
 
22
- This plugin is only useful for assigning custom permalinks for *individual* posts, pages, tags or categories.
23
- It will not apply whole permalink structures or automatically apply a category's custom permalink to the posts
24
- within that category.
25
 
26
  > If anyone wants the different Structure Tags for their Post types or use symbols in the URLs So, use the [Permalinks Customizer](https://wordpress.org/plugins/permalinks-customizer/) which is a fork of this plugin and contains the enhancement of this plugin.
27
 
28
  == Privacy Policy ==
29
 
30
- This plugin doesn't collect/store any user related information.
31
 
32
- To have any kind of further query please feel free to [contact us](https://www.custompermalinks.com/contact-us/).
 
 
 
 
 
 
 
 
33
 
34
  == Filters ==
35
 
36
- The plugin provides some filter which may be used according to your needs.
37
 
38
- To exclude any Permalink to processed with the plugin so, just add the filter looks like this:
39
  `
40
- function yasglobal_xml_sitemap_url( $permalink ) {
41
- if ( false !== strpos( $permalink, 'sitemap.xml' )) {
42
- return '__true';
43
- }
44
- return;
 
 
45
  }
46
  add_filter( 'custom_permalinks_request_ignore', 'yasglobal_xml_sitemap_url' );
47
  `
48
 
 
 
49
  To exclude permalink from any post type so, just add the filter looks like this:
50
  `
51
- function yasglobal_exclude_post_types( $post_type ) {
52
- if ( $post_type == 'custompost' ) {
53
- return '__true';
54
- }
55
- return '__false';
 
 
56
  }
57
- add_filter( 'custom_permalinks_exclude_post_type', 'yasglobal_exclude_post_types');
58
  `
59
 
60
- Note: custom_permalinks_exclude_post_type doesn't work on the post's permalink which has been created previously.
 
 
61
 
62
- To remove the like query to being work just add this line in your theme's functions.php:
63
  `
64
- add_filter( 'cp_remove_like_query', '__return_false');
 
 
 
 
 
 
 
 
65
  `
66
 
67
- Note: Use `custom_permalinks_like_query` filter if the URLs doesn't work for you after upgrading to `v1.2.9`
 
 
68
 
69
- To add `PATH_INFO` in `$_SERVER` Variable just add this line in your theme's functions.php:
70
  `
71
- add_filter( 'custom_permalinks_path_info', '__return_true');
 
 
 
 
 
 
 
 
72
  `
73
 
74
  === Thanks for the Support ===
@@ -78,7 +106,7 @@ One-on-one email support is available to people who bought [Custom Permalinks Pr
78
 
79
  === Bug reports ===
80
 
81
- Bug reports for Custom Permalinks are [welcomed on GitHub](https://github.com/yasglobal/custom-permalinks). Please note GitHub is not a support forum, and issues that aren't properly qualified as bugs will be closed.
82
 
83
  == Installation ==
84
 
@@ -97,9 +125,27 @@ This process defines you the steps to follow either you are installing through W
97
 
98
  == Changelog ==
99
 
100
- = 1.5.1 - Jun 11, 2019 =
101
 
102
  * Bugs
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  * Added additional check for [Call to undefined function pll_current_language](https://wordpress.org/support/topic/call-to-undefined-function-pll_current_language/)
104
 
105
  = 1.5.0 - Jun 04, 2019 =
@@ -110,13 +156,13 @@ This process defines you the steps to follow either you are installing through W
110
 
111
  = 1.4.0 - Nov 08, 2018 =
112
 
113
- * Enhancement
114
  * Added Support for Gutenberg
115
  * Set meta_keys to be protected to stop duplication in Custom Fields
116
 
117
  = 1.3.0 - June 07, 2018 =
118
 
119
- * Enhancement
120
  * [Conflict with WPML](https://wordpress.org/support/topic/conflict-with-wpml-17/)
121
  * Avoid appending slashes and use trailingslashit instead
122
 
1
  === Custom Permalinks ===
2
  Contributors: sasiddiqui, michaeltyson
 
3
  Tags: permalink, url, link, address, custom, redirect, custom post type, GDPR, GDPR Compliant
4
  Requires at least: 2.6
5
+ Tested up to: 5.4
6
+ Stable tag: 1.6.0
7
  License: GPLv3
8
  License URI: https://www.gnu.org/licenses/gpl.html
9
 
11
 
12
  == Description ==
13
 
14
+ Lay out your site the way *you* want it. Set the URL of any post, page, tag or category to anything you want. Old permalinks will redirect properly to the new address. Custom Permalinks gives you ultimate control over your site structure.
 
 
15
 
16
+ > Be warned: *This plugin is not a replacement for WordPress's built-in permalink system*. Check your WordPress administration's "Permalinks" settings page first, to make sure that this doesn't already meet your needs.
 
17
 
18
+ This plugin is only useful for assigning custom permalinks for *individual* posts, pages, tags or categories. It will not apply whole permalink structures or automatically apply a category's custom permalink to the posts within that category.
 
 
19
 
20
  > If anyone wants the different Structure Tags for their Post types or use symbols in the URLs So, use the [Permalinks Customizer](https://wordpress.org/plugins/permalinks-customizer/) which is a fork of this plugin and contains the enhancement of this plugin.
21
 
22
  == Privacy Policy ==
23
 
24
+ This plugin only collects the following information.
25
 
26
+ 1. Administration Email Address (Only the email that is set in the WordPress setting)
27
+ 2. Plugin version
28
+ 3. Site Title
29
+ 4. WordPress Address (URL)
30
+ 5. WordPress version
31
+
32
+ All this information gets collected when the plugin is installed or updated.
33
+
34
+ To have any kind of query please feel free to [contact us](https://www.custompermalinks.com/contact-us/).
35
 
36
  == Filters ==
37
 
38
+ === Exclude permalink to be processed ===
39
 
40
+ To exclude any Permalink to be processed with the plugin, add the filter looks like this:
41
  `
42
+ function yasglobal_xml_sitemap_url( $permalink )
43
+ {
44
+ if ( false !== strpos( $permalink, 'sitemap.xml' ) ) {
45
+ return '__true';
46
+ }
47
+
48
+ return;
49
  }
50
  add_filter( 'custom_permalinks_request_ignore', 'yasglobal_xml_sitemap_url' );
51
  `
52
 
53
+ === Exclude PostType ===
54
+
55
  To exclude permalink from any post type so, just add the filter looks like this:
56
  `
57
+ function yasglobal_exclude_post_types( $post_type )
58
+ {
59
+ if ( 'custompost' === $post_type ) {
60
+ return '__true';
61
+ }
62
+
63
+ return '__false';
64
  }
65
+ add_filter( 'custom_permalinks_exclude_post_type', 'yasglobal_exclude_post_types' );
66
  `
67
 
68
+ Note: `custom_permalinks_exclude_post_type` doesn't work on the posts permalink which has been created previously.
69
+
70
+ === Exclude Posts ===
71
 
72
+ To exclude permalink from any posts (based on ID, Template, etc), just add the filter looks like this:
73
  `
74
+ function yasglobal_exclude_posts( $post )
75
+ {
76
+ if ( 1557 === $post->ID ) {
77
+ return true;
78
+ }
79
+
80
+ return false;
81
+ }
82
+ add_filter( 'custom_permalinks_exclude_posts', 'yasglobal_exclude_posts' );
83
  `
84
 
85
+ Note: `custom_permalinks_exclude_posts` doesn't wor k on the posts permalink which has been created previously.
86
+
87
+ === Remove `like` query ===
88
 
89
+ To remove `like` query to being work, add below-mentioned line in your theme `functions.php`:
90
  `
91
+ add_filter( 'cp_remove_like_query', '__return_false' );
92
+ `
93
+
94
+ Note: Use `custom_permalinks_like_query` filter if the URLs doesn't works for you after upgrading to `v1.2.9`.
95
+
96
+ === Add `PATH_INFO` in `$_SERVER` Variable ===
97
+
98
+ `
99
+ add_filter( 'custom_permalinks_path_info', '__return_true' );
100
  `
101
 
102
  === Thanks for the Support ===
106
 
107
  === Bug reports ===
108
 
109
+ Bug reports for Custom Permalinks are [welcomed on GitHub](https://github.com/samiahmedsiddiqui/custom-permalinks). Please note GitHub is not a support forum, and issues that aren't properly qualified as bugs will be closed.
110
 
111
  == Installation ==
112
 
125
 
126
  == Changelog ==
127
 
128
+ = 1.6.0 - Aug 08, 2020 =
129
 
130
  * Bugs
131
+ * [Undefined index and undefined variable error](https://github.com/samiahmedsiddiqui/custom-permalinks/issues/28)
132
+ * [count(): Parameter must be an array or an object](https://github.com/samiahmedsiddiqui/custom-permalinks/issues/27)
133
+ * Fix double slash from the permalink form
134
+ * [use 'view_item' label for previewing custom post types](https://github.com/samiahmedsiddiqui/custom-permalinks/issues/31)
135
+ * [Fix PHP 7.4 issues](https://github.com/samiahmedsiddiqui/custom-permalinks/issues/32)
136
+ * Fix Yoast Canonical double slash issue
137
+ * [Replacing category_link with term_link](https://github.com/samiahmedsiddiqui/custom-permalinks/issues/34)
138
+ * [Bug with WPML and Use directory for default language](https://github.com/samiahmedsiddiqui/custom-permalinks/issues/36)
139
+ * Fix Static Homepage redirect issue
140
+ * Enhancements
141
+ * Improved Gutenberg Support
142
+ * Added compatibility for WPML language switcher
143
+ * Add filter to exclude Custom Permalinks for certain posts (based on Post IDs, template, etc)
144
+ * Optimized Code
145
+
146
+ = 1.5.1 - Jun 11, 2019 =
147
+
148
+ * Bug
149
  * Added additional check for [Call to undefined function pll_current_language](https://wordpress.org/support/topic/call-to-undefined-function-pll_current_language/)
150
 
151
  = 1.5.0 - Jun 04, 2019 =
156
 
157
  = 1.4.0 - Nov 08, 2018 =
158
 
159
+ * Enhancements
160
  * Added Support for Gutenberg
161
  * Set meta_keys to be protected to stop duplication in Custom Fields
162
 
163
  = 1.3.0 - June 07, 2018 =
164
 
165
+ * Enhancements
166
  * [Conflict with WPML](https://wordpress.org/support/topic/conflict-with-wpml-17/)
167
  * Avoid appending slashes and use trailingslashit instead
168
 
uninstall.php CHANGED
@@ -4,7 +4,7 @@
4
  *
5
  * Deletes Option and Post Permalinks on uninstalling the Plugin.
6
  *
7
- * @package CustomPermalinks/Uninstaller
8
  * @since 1.2.18
9
  */
10
 
4
  *
5
  * Deletes Option and Post Permalinks on uninstalling the Plugin.
6
  *
7
+ * @package CustomPermalinks
8
  * @since 1.2.18
9
  */
10