Custom Post Type Permalinks - Version 0.9.3.3

Version Description

  • Fix Override Page Permalink Bug.
  • has_archive Bug Fix.
Download this release

Release Info

Developer Toro_Unit
Plugin Icon 128x128 Custom Post Type Permalinks
Version 0.9.3.3
Comparing to
See all releases

Code changes from version 0.9.3.2 to 0.9.3.3

Files changed (2) hide show
  1. custom-post-type-permalinks.php +811 -806
  2. readme.txt +18 -11
custom-post-type-permalinks.php CHANGED
@@ -1,806 +1,811 @@
1
- <?php
2
- /*
3
- Plugin Name: Custom Post Type Permalinks
4
- Plugin URI: http://www.torounit.com
5
- Description: Add post archives of custom post type and customizable permalinks.
6
- Author: Toro_Unit
7
- Author URI: http://www.torounit.com/plugins/custom-post-type-permalinks/
8
- Version: 0.9.3.2
9
- Text Domain: cptp
10
- License: GPL2 or later
11
- Domain Path: /language/
12
- */
13
-
14
-
15
- /* Copyright 2012 Toro_Unit (email : mail@torounit.com)
16
-
17
- This program is free software; you can redistribute it and/or modify
18
- it under the terms of the GNU General Public License as published by
19
- the Free Software Foundation; either version 2 of the License, or
20
- (at your option) any later version.
21
-
22
- This program is distributed in the hope that it will be useful,
23
- but WITHOUT ANY WARRANTY; without even the implied warranty of
24
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
- GNU General Public License for more details.
26
-
27
- You should have received a copy of the GNU General Public License
28
- along with this program; if not, write to the Free Software
29
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30
- */
31
-
32
-
33
-
34
- /**
35
- *
36
- * Custom Post Type Permalinks
37
- *
38
- *
39
- */
40
- class Custom_Post_Type_Permalinks {
41
-
42
-
43
-
44
-
45
- public $version = "0.9";
46
-
47
- public $default_structure = '/%postname%/';
48
-
49
- /**
50
- *
51
- * Add Action & filter hooks.
52
- *
53
- */
54
- public function add_hook () {
55
-
56
- add_action( 'plugins_loaded', array(&$this,'check_version') );
57
- add_action( 'wp_loaded', array(&$this,'add_archive_rewrite_rules'), 99 );
58
- add_action( 'wp_loaded', array(&$this,'add_tax_rewrite_rules') );
59
- add_action( 'wp_loaded', array(&$this, "dequeue_flush_rules"),100);
60
- add_action( 'parse_request', array(&$this, "parse_request") );
61
- add_action( 'registered_post_type', array(&$this,'registered_post_type'), 10, 2 );
62
-
63
-
64
- if(get_option( "permalink_structure") != "") {
65
- add_filter( 'post_type_link', array(&$this,'post_type_link'), 10, 4 );
66
- add_filter( 'getarchives_join', array(&$this,'getarchives_join'), 10, 2 ); // [steve]
67
- add_filter( 'getarchives_where', array(&$this,'getarchives_where'), 10 , 2 );
68
- add_filter( 'get_archives_link', array(&$this,'get_archives_link'), 20, 1 );
69
- add_filter( 'term_link', array(&$this,'term_link'), 10, 3 );
70
- add_filter( 'attachment_link', array(&$this, 'attachment_link'), 20 , 2);
71
- }
72
-
73
-
74
- add_action( 'init', array(&$this,'load_textdomain') );
75
- add_action( 'init', array(&$this, 'update_rules') );
76
- add_action( 'update_option_cptp_version', array(&$this, 'update_rules') );
77
- add_action( 'admin_init', array(&$this,'settings_api_init'), 30 );
78
- add_action( 'admin_enqueue_scripts', array(&$this,'enqueue_css_js') );
79
- add_action( 'admin_footer', array(&$this,'pointer_js') );
80
-
81
-
82
- }
83
-
84
- /**
85
- *
86
- * dequeue flush rules
87
- * @since 0.9
88
- *
89
- */
90
-
91
- public function dequeue_flush_rules () {
92
- if(get_option("queue_flush_rules")){
93
- flush_rewrite_rules();
94
- update_option( "queue_flush_rules", 0 );
95
-
96
- }
97
- }
98
-
99
-
100
- /**
101
- *
102
- * dequeue flush rules
103
- * @since 0.8.6
104
- *
105
- */
106
-
107
- public function check_version() {
108
- $version = get_option('cptp_version', 0);
109
- if($version != $this->version) {
110
- update_option('cptp_version', $this->version);
111
- }
112
- }
113
-
114
- /**
115
- *
116
- * Get Custom Taxonomies parents.
117
- * @version 1.0
118
- *
119
- */
120
- private function get_taxonomy_parents( $id, $taxonomy = 'category', $link = false, $separator = '/', $nicename = false, $visited = array() ) {
121
- $chain = '';
122
- $parent = &get_term( $id, $taxonomy, OBJECT, 'raw');
123
- if ( is_wp_error( $parent ) ) {
124
- return $parent;
125
- }
126
-
127
- if ( $nicename ){
128
- $name = $parent->slug;
129
- }else {
130
- $name = $parent->name;
131
- }
132
-
133
- if ( $parent->parent && ( $parent->parent != $parent->term_id ) && !in_array( $parent->parent, $visited ) ) {
134
- $visited[] = $parent->parent;
135
- $chain .= $this->get_taxonomy_parents( $parent->parent, $taxonomy, $link, $separator, $nicename, $visited );
136
- }
137
-
138
- if ( $link ) {
139
- $chain .= '<a href="' . get_term_link( $parent->term_id, $taxonomy ) . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $parent->name ) ) . '">'.$name.'</a>' . $separator;
140
- }else {
141
- $chain .= $name.$separator;
142
- }
143
- return $chain;
144
- }
145
-
146
-
147
-
148
- /**
149
- *
150
- * Add rewrite rules for archives.
151
- * @version 1.1
152
- *
153
- */
154
- public function add_archive_rewrite_rules() {
155
- $post_types = get_post_types( array('_builtin'=>false, 'publicly_queryable'=>true,'show_ui' => true) );
156
-
157
- foreach ( $post_types as $post_type ):
158
- if( !$post_type ) {
159
- continue;
160
- }
161
-
162
- $permalink = get_option( $post_type.'_structure' );
163
- $post_type_obj = get_post_type_object($post_type);
164
- $slug = $post_type_obj->rewrite['slug'];
165
- if( !$slug )
166
- $slug = $post_type;
167
-
168
- if( $post_type_obj->has_archive ){
169
- if( is_string( $post_type_obj->has_archive ) ){
170
- $slug = $post_type_obj->has_archive;
171
- };
172
-
173
-
174
- add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&feed=$matches[4]&post_type='.$post_type, 'top' );
175
- add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/(feed|rdf|rss|rss2|atom)/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&feed=$matches[4]&post_type='.$post_type, 'top' );
176
- add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/page/?([0-9]{1,})/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&paged=$matches[4]&post_type='.$post_type, 'top' );
177
- add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&post_type='.$post_type, 'top' );
178
- add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&feed=$matches[3]&post_type='.$post_type, 'top' );
179
- add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/(feed|rdf|rss|rss2|atom)/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&feed=$matches[3]&post_type='.$post_type, 'top' );
180
- add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/page/?([0-9]{1,})/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&paged=$matches[3]&post_type='.$post_type, 'top' );
181
- add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&post_type='.$post_type, 'top' );
182
- add_rewrite_rule( $slug.'/date/([0-9]{4})/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?year=$matches[1]&feed=$matches[2]&post_type='.$post_type, 'top' );
183
- add_rewrite_rule( $slug.'/date/([0-9]{4})/(feed|rdf|rss|rss2|atom)/?$', 'index.php?year=$matches[1]&feed=$matches[2]&post_type='.$post_type, 'top' );
184
- add_rewrite_rule( $slug.'/date/([0-9]{4})/page/?([0-9]{1,})/?$', 'index.php?year=$matches[1]&paged=$matches[2]&post_type='.$post_type, 'top' );
185
- add_rewrite_rule( $slug.'/date/([0-9]{4})/?$', 'index.php?year=$matches[1]&post_type='.$post_type, 'top' );
186
- add_rewrite_rule( $slug.'/author/([^/]+)/?$', 'index.php?author_name=$matches[1]&post_type='.$post_type, 'top' );
187
- }
188
-
189
-
190
- endforeach;
191
- }
192
-
193
- /**
194
- *
195
- * registered_post_type
196
- * ** add rewrite tag for Custom Post Type.
197
- * @version 1.1
198
- * @since 0.9
199
- *
200
- */
201
-
202
- public function registered_post_type( $post_type, $args ) {
203
-
204
- global $wp_post_types, $wp_rewrite, $wp;
205
-
206
- if( $args->_builtin or !$args->publicly_queryable or !$args->show_ui ){
207
- return false;
208
- }
209
- $permalink = get_option( $post_type.'_structure' );
210
-
211
- if( !$permalink ) {
212
- $permalink = $this->default_structure;
213
- }
214
-
215
- $permalink = '%'.$post_type.'_slug%'.$permalink;
216
- $permalink = str_replace( '%postname%', '%'.$post_type.'%', $permalink );
217
-
218
- add_rewrite_tag( '%'.$post_type.'_slug%', '('.$args->rewrite['slug'].')','post_type='.$post_type.'&slug=' );
219
-
220
- $taxonomies = get_taxonomies( array("show_ui" => true, "_builtin" => false), 'objects' );
221
- foreach ( $taxonomies as $taxonomy => $objects ):
222
- $wp_rewrite->add_rewrite_tag( "%$taxonomy%", '(.+?)', "$taxonomy=" );
223
- endforeach;
224
-
225
- $permalink = trim($permalink, "/" );
226
- add_permastruct( $post_type, $permalink, $args->rewrite );
227
-
228
- }
229
-
230
-
231
-
232
-
233
-
234
- /**
235
- *
236
- * fix attachment output
237
- *
238
- * @version 1.0
239
- * @since 0.8.2
240
- *
241
- */
242
-
243
- public function attachment_link( $link , $postID ) {
244
- $post = get_post( $postID );
245
- if (!$post->post_parent){
246
- return $link;
247
- }
248
- $post_parent = get_post( $post->post_parent );
249
- $permalink = get_option( $post_parent->post_type.'_structure' );
250
- $post_type = get_post_type_object( $post_parent->post_type );
251
-
252
- if( $post_type->_builtin == false ) {
253
- if(strpos( $permalink, "%postname%" ) < strrpos( $permalink, "%post_id%" ) && strrpos( $permalink, "attachment/" ) === FALSE ){
254
- $link = str_replace($post->post_name , "attachment/".$post->post_name, $link);
255
- }
256
- }
257
-
258
- return $link;
259
- }
260
-
261
-
262
-
263
- /**
264
- *
265
- * Fix permalinks output.
266
- *
267
- * @param String $post_link
268
- * @param Object $post 投稿情報
269
- * @param String $leavename 記事編集画面でのみ渡される
270
- *
271
- * @version 2.0
272
- *
273
- */
274
- public function post_type_link( $post_link, $post, $leavename ) {
275
-
276
- global $wp_rewrite;
277
- $draft_or_pending = isset( $post->post_status ) && in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft' ) );
278
- if( $draft_or_pending and !$leavename )
279
- return $post_link;
280
-
281
- $post_type = $post->post_type;
282
- $permalink = $wp_rewrite->get_extra_permastruct( $post_type );
283
- $permalink = str_replace( '%post_id%', $post->ID, $permalink );
284
- $permalink = str_replace( '%'.$post_type.'_slug%', get_post_type_object( $post_type )->rewrite['slug'], $permalink );
285
-
286
-
287
- $parentsDirs = "";
288
- if( !$leavename ){
289
- $postId = $post->ID;
290
- while ($parent = get_post($postId)->post_parent) {
291
- $parentsDirs = get_post($parent)->post_name."/".$parentsDirs;
292
- $postId = $parent;
293
- }
294
- }
295
-
296
- $permalink = str_replace( '%'.$post_type.'%', $parentsDirs.'%'.$post_type.'%', $permalink );
297
-
298
- if( !$leavename ){
299
- $permalink = str_replace( '%'.$post_type.'%', $post->post_name, $permalink );
300
- }
301
-
302
- //%post_id%/attachment/%attachement_name%;
303
- //画像の編集ページでのリンク
304
- if( isset($_GET["post"]) && $_GET["post"] != $post->ID ) {
305
- $parent_structure = trim(get_option( $post->post_type.'_structure' ), "/");
306
- if( "%post_id%" == $parent_structure or "%post_id%" == array_pop( explode( "/", $parent_structure ) ) ) {
307
- $permalink = $permalink."/attachment/";
308
- };
309
- }
310
-
311
- $taxonomies = get_taxonomies( array('show_ui' => true),'objects' );
312
-
313
- //%taxnomomy% -> parent/child
314
- //運用でケアすべきかも。
315
- foreach ( $taxonomies as $taxonomy => $objects ) {
316
- if ( strpos($permalink, "%$taxonomy%") !== false ) {
317
- $terms = wp_get_post_terms( $post->ID, $taxonomy, array('orderby' => 'term_id'));
318
- if ( $terms and count($terms) > 1 ) {
319
- if(reset($terms)->parent == 0){
320
-
321
- $keys = array_keys($terms);
322
- $term = $terms[$keys[1]]->slug;
323
- if ( $terms[$keys[0]]->term_id == $terms[$keys[1]]->parent ) {
324
- $term = $this->get_taxonomy_parents( $terms[$keys[1]]->parent,$taxonomy, false, '/', true ) . $term;
325
- }
326
- }else{
327
- $keys = array_keys($terms);
328
- $term = $terms[$keys[0]]->slug;
329
- if ( $terms[$keys[1]]->term_id == $terms[$keys[0]]->parent ) {
330
- $term = $this->get_taxonomy_parents( $terms[$keys[0]]->parent,$taxonomy, false, '/', true ) . $term;
331
- }
332
- }
333
- }else if( $terms ){
334
-
335
- $term_obj = array_shift($terms);
336
- $term = $term_obj->slug;
337
-
338
- if(isset($term_obj->parent) and $term_obj->parent != 0) {
339
- $term = $this->get_taxonomy_parents( $term_obj->parent,$taxonomy, false, '/', true ) . $term;
340
- }
341
- }
342
-
343
- if( isset($term) ) {
344
- $permalink = str_replace( "%$taxonomy%", $term, $permalink );
345
- }
346
- }
347
- }
348
-
349
- $user = get_userdata( $post->post_author );
350
- if(isset($user->user_nicename)) {
351
- $permalink = str_replace( "%author%", $user->user_nicename, $permalink );
352
- }
353
-
354
- $post_date = strtotime( $post->post_date );
355
- $permalink = str_replace( "%year%", date("Y",$post_date), $permalink );
356
- $permalink = str_replace( "%monthnum%", date("m",$post_date), $permalink );
357
- $permalink = str_replace( "%day%", date("d",$post_date), $permalink );
358
- $permalink = str_replace( "%hour%", date("H",$post_date), $permalink );
359
- $permalink = str_replace( "%minute%", date("i",$post_date), $permalink );
360
- $permalink = str_replace( "%second%", date("s",$post_date), $permalink );
361
-
362
-
363
- $permalink = home_url()."/".user_trailingslashit( $permalink );
364
- $permalink = str_replace("//", "/", $permalink);
365
- $permalink = str_replace(":/", "://", $permalink);
366
- return $permalink;
367
- }
368
-
369
-
370
-
371
- /**
372
- *
373
- * wp_get_archives fix for custom post
374
- * Ex:wp_get_archives('&post_type='.get_query_var( 'post_type' ));
375
- * @version 2.0
376
- *
377
- */
378
-
379
- public $get_archives_where_r;
380
-
381
- // function modified by [steve]
382
- public function getarchives_where( $where, $r ) {
383
- $this->get_archives_where_r = $r;
384
- if ( isset($r['post_type']) ) {
385
- $where = str_replace( '\'post\'', '\'' . $r['post_type'] . '\'', $where );
386
- }
387
-
388
- if(isset($r['taxonomy']) && is_array($r['taxonomy']) ){
389
- global $wpdb;
390
- $where = $where . " AND $wpdb->term_taxonomy.taxonomy = '".$r['taxonomy']['name']."' AND $wpdb->term_taxonomy.term_id = '".$r['taxonomy']['termid']."'";
391
- }
392
-
393
- return $where;
394
- }
395
-
396
-
397
-
398
- //function added by [steve]
399
- /**
400
- *
401
- * get_archive_join
402
- * @author Steve
403
- * @since 0.8
404
- * @version 1.0
405
- *
406
- *
407
- */
408
- public function getarchives_join( $join, $r ) {
409
- global $wpdb;
410
- $this->get_archives_where_r = $r;
411
- if(isset($r['taxonomy']) && is_array($r['taxonomy']) )
412
- $join = $join . " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
413
-
414
- return $join;
415
- }
416
-
417
-
418
-
419
- /**
420
- *
421
- * get_arcihves_link
422
- * @version 2.1
423
- *
424
- */
425
- public function get_archives_link( $link ) {
426
- if(!isset($this->get_archives_where_r['post_type'])) {
427
- return $link;
428
- }
429
- $c = isset($this->get_archives_where_r['taxonomy']) && is_array($this->get_archives_where_r['taxonomy']) ? $this->get_archives_where_r['taxonomy'] : ""; //[steve]
430
- $t = $this->get_archives_where_r['post_type'];
431
-
432
-
433
- $this->get_archives_where_r['post_type'] = isset($this->get_archives_where_r['post_type_slug']) ? $this->get_archives_where_r['post_type_slug'] : $t; // [steve] [*** bug fixing]
434
-
435
- if (isset($this->get_archives_where_r['post_type']) and $this->get_archives_where_r['type'] != 'postbypost'){
436
- $blog_url = rtrim( get_bloginfo("url") ,'/');
437
-
438
- //remove .ext
439
- $str = preg_replace("/\.[a-z,_]*/","",get_option("permalink_structure"));
440
-
441
- if($str = rtrim( preg_replace("/%[a-z,_]*%/","",$str) ,'/')) { // /archive/%post_id%
442
- $ret_link = str_replace($str, '/'.'%link_dir%', $link);
443
- }else{
444
- $blog_url = preg_replace('/https?:\/\//', '', $blog_url);
445
- $ret_link = str_replace($blog_url,$blog_url.'/'.'%link_dir%',$link);
446
- }
447
-
448
- $post_type = get_post_type_object( $this->get_archives_where_r['post_type'] );
449
- if(empty($c) ){ // [steve]
450
- if(isset( $post_type->rewrite["slug"] )) {
451
- $link_dir = $post_type->rewrite["slug"];
452
- }
453
- else{
454
- $link_dir = $this->get_archives_where_r['post_type'];
455
- }
456
- }
457
- else{ // [steve]
458
- $c['name'] = ($c['name'] == 'category' && get_option('category_base')) ? get_option('category_base') : $c['name'];
459
- $link_dir = $post_type->rewrite["slug"]."/".$c['name']."/".$c['termslug'];
460
- }
461
-
462
- if(!strstr($link,'/date/')){
463
- $link_dir = $link_dir .'/date';
464
- }
465
-
466
- $ret_link = str_replace('%link_dir%',$link_dir,$ret_link);
467
- }else {
468
- $ret_link = $link;
469
- }
470
- $this->get_archives_where_r['post_type'] = $t; // [steve] reverting post_type to previous value
471
-
472
- return $ret_link;
473
- }
474
-
475
-
476
-
477
- /**
478
- *
479
- * Add rewrite rules for custom taxonomies.
480
- * @since 0.6
481
- * @version 2.1
482
- *
483
- */
484
- public function add_tax_rewrite_rules() {
485
- if(get_option('no_taxonomy_structure')) {
486
- return false;
487
- }
488
-
489
-
490
- global $wp_rewrite;
491
- $taxonomies = get_taxonomies(array( '_builtin' => false));
492
- $taxonomies['category'] = 'category';
493
-
494
- if(empty($taxonomies)) {
495
- return false;
496
- }
497
-
498
- foreach ($taxonomies as $taxonomy) :
499
- $taxonomyObject = get_taxonomy($taxonomy);
500
- $post_types = $taxonomyObject->object_type;
501
-
502
- foreach ($post_types as $post_type):
503
- $post_type_obj = get_post_type_object($post_type);
504
- $slug = $post_type_obj->rewrite['slug'];
505
- if(!$slug) {
506
- $slug = $post_type;
507
- }
508
-
509
- if(is_string($post_type_obj->has_archive)) {
510
- $slug = $post_type_obj->has_archive;
511
- };
512
-
513
- if ( $taxonomy == 'category' ){
514
- $taxonomypat = ($cb = get_option('category_base')) ? $cb : $taxonomy;
515
- $tax = 'category_name';
516
- } else {
517
- // Edit by [Xiphe]
518
- if (isset($taxonomyObject->rewrite['slug'])) {
519
- $taxonomypat = $taxonomyObject->rewrite['slug'];
520
- } else {
521
- $taxonomypat = $taxonomy;
522
- }
523
- // [Xiphe] stop
524
-
525
- $tax = $taxonomy;
526
- }
527
-
528
-
529
- //add taxonomy slug
530
- add_rewrite_rule( $slug.'/'.$taxonomypat.'/(.+?)/page/?([0-9]{1,})/?$', 'index.php?'.$tax.'=$matches[1]&paged=$matches[2]', 'top' );
531
- add_rewrite_rule( $slug.'/'.$taxonomypat.'/(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?'.$tax.'=$matches[1]&feed=$matches[2]', 'top' );
532
- add_rewrite_rule( $slug.'/'.$taxonomypat.'/(.+?)/(feed|rdf|rss|rss2|atom)/?$', 'index.php?'.$tax.'=$matches[1]&feed=$matches[2]', 'top' );
533
- add_rewrite_rule( $slug.'/'.$taxonomypat.'/(.+?)/?$', 'index.php?'.$tax.'=$matches[1]', 'top' ); // modified by [steve] [*** bug fixing]
534
-
535
- // below rules were added by [steve]
536
- add_rewrite_rule( $taxonomypat.'/(.+?)/date/([0-9]{4})/([0-9]{1,2})/?$', 'index.php?'.$tax.'=$matches[1]&year=$matches[2]&monthnum=$matches[3]&post_type='.$post_type, 'top' );
537
- add_rewrite_rule( $taxonomypat.'/(.+?)/date/([0-9]{4})/([0-9]{1,2})/page/?([0-9]{1,})/?$', 'index.php?'.$tax.'=$matches[1]&year=$matches[2]&monthnum=$matches[3]&paged=$matches[4]&post_type='.$post_type, 'top' );
538
- add_rewrite_rule( $slug.'/'.$taxonomypat.'/(.+?)/date/([0-9]{4})/([0-9]{1,2})/?$', 'index.php?'.$tax.'=$matches[1]&year=$matches[2]&monthnum=$matches[3]&post_type='.$post_type, 'top' );
539
- add_rewrite_rule( $slug.'/'.$taxonomypat.'/(.+?)/date/([0-9]{4})/([0-9]{1,2})/page/?([0-9]{1,})/?$', 'index.php?'.$tax.'=$matches[1]&year=$matches[2]&monthnum=$matches[3]&paged=$matches[4]&post_type='.$post_type, 'top' );
540
-
541
- endforeach;
542
- endforeach;
543
- }
544
-
545
-
546
-
547
-
548
- /**
549
- *
550
- * Fix taxonomy link outputs.
551
- * @since 0.6
552
- * @version 1.0
553
- *
554
- */
555
- public function term_link( $termlink, $term, $taxonomy ) {
556
- if( get_option('no_taxonomy_structure') ) {
557
- return $termlink;
558
- }
559
-
560
- $taxonomy = get_taxonomy($taxonomy);
561
- if( $taxonomy->_builtin )
562
- return $termlink;
563
-
564
- if( empty($taxonomy) )
565
- return $termlink;
566
-
567
- $wp_home = rtrim( home_url(), '/' );
568
-
569
- $post_type = $taxonomy->object_type[0];
570
- $slug = get_post_type_object($post_type)->rewrite['slug'];
571
- $with_front = get_post_type_object($post_type)->rewrite['with_front'];
572
-
573
- //$termlink = str_replace( $term->slug.'/', $this->get_taxonomy_parents( $term->term_id,$taxonomy->name, false, '/', true ), $termlink );
574
- $str = rtrim( preg_replace( "/%[a-z_]*%/", "" ,get_option("permalink_structure")) ,'/' );//remove with front
575
- $termlink = str_replace($str."/", "/", $termlink );
576
-
577
- if( $with_front === false ) {
578
- $str = "";
579
- }
580
- $slug = $str."/".$slug;
581
-
582
- $termlink = str_replace( $wp_home, $wp_home.$slug, $termlink );
583
- $termlink = str_replace( $term->slug.'/', $this->get_taxonomy_parents( $term->term_id,$taxonomy->name, false, '/', true ), $termlink );
584
- return $termlink;
585
- }
586
-
587
- /**
588
- *
589
- * Fix taxonomy = parent/child => taxonomy => child
590
- * @since 0.9.3
591
- *
592
- */
593
- public function parse_request($obj) {
594
- $taxes = get_taxonomies(array( '_builtin' => false));
595
- foreach ($taxes as $key => $tax) {
596
- if(isset($obj->query_vars[$tax])) {
597
- if(strpos( $obj->query_vars[$tax] ,"/") !== false ) {
598
- $obj->query_vars[$tax] = array_pop(explode("/", $obj->query_vars[$tax]));
599
- }
600
- }
601
- }
602
- }
603
-
604
-
605
-
606
- /**
607
- *
608
- * load textdomain
609
- * @since 0.6.2
610
- *
611
- */
612
- public function load_textdomain() {
613
- load_plugin_textdomain('cptp',false,'custom-post-type-permalinks/language');
614
- }
615
-
616
-
617
-
618
- /**
619
- *
620
- * Add hook flush_rules
621
- * @since 0.7.9
622
- *
623
- */
624
- public function update_rules() {
625
-
626
- $post_types = get_post_types( array('_builtin'=>false, 'publicly_queryable'=>true, 'show_ui' => true) );
627
- $type_count = count($post_types);
628
- $i = 0;
629
- foreach ($post_types as $post_type):
630
- add_action('update_option_'.$post_type.'_structure',array(&$this,'queue_flush_rules'),10,2);
631
- endforeach;
632
- add_action('update_option_no_taxonomy_structure',array(&$this,'queue_flush_rules'),10,2);
633
- }
634
-
635
-
636
-
637
- /**
638
- * Flush rules
639
- *
640
- * @since 0.7.9
641
- *
642
- */
643
-
644
- public function queue_flush_rules(){
645
- update_option( "queue_flush_rules", 1 );
646
- }
647
-
648
-
649
-
650
- /**
651
- *
652
- * Setting Init
653
- * @since 0.7
654
- *
655
- */
656
- public function settings_api_init() {
657
- add_settings_section('cptp_setting_section',
658
- __("Permalink Setting for custom post type",'cptp'),
659
- array(&$this,'setting_section_callback_function'),
660
- 'permalink'
661
- );
662
-
663
- $post_types = get_post_types( array('_builtin'=>false, 'publicly_queryable'=>true, 'show_ui' => true) );
664
- foreach ($post_types as $post_type):
665
- if(isset($_POST['submit']) and isset($_POST['_wp_http_referer'])){
666
- if( strpos($_POST['_wp_http_referer'],'options-permalink.php') !== FALSE ) {
667
-
668
- $structure = trim(esc_attr($_POST[$post_type.'_structure']));#get setting
669
-
670
- #default permalink structure
671
- if( !$structure )
672
- $structure = $this->default_structure;
673
-
674
- $structure = str_replace('//','/','/'.$structure);# first "/"
675
-
676
- #last "/"
677
- $lastString = substr(trim(esc_attr($_POST['permalink_structure'])),-1);
678
- $structure = rtrim($structure,'/');
679
-
680
- if ( $lastString == '/')
681
- $structure = $structure.'/';
682
-
683
- update_option($post_type.'_structure', $structure );
684
- }
685
- }
686
-
687
- add_settings_field($post_type.'_structure',
688
- $post_type,
689
- array(&$this,'setting_structure_callback_function'),
690
- 'permalink',
691
- 'cptp_setting_section',
692
- $post_type.'_structure'
693
- );
694
-
695
- register_setting('permalink',$post_type.'_structure');
696
- endforeach;
697
-
698
- add_settings_field(
699
- 'no_taxonomy_structure',
700
- __("Use custom permalink of custom taxonomy archive.",'cptp'),
701
- array(&$this,'setting_no_tax_structure_callback_function'),
702
- 'permalink',
703
- 'cptp_setting_section'
704
- );
705
-
706
- register_setting('permalink','no_taxonomy_structure');
707
-
708
- if(isset($_POST['submit']) && isset($_POST['_wp_http_referer']) && strpos($_POST['_wp_http_referer'],'options-permalink.php') !== FALSE ) {
709
-
710
- if(!isset($_POST['no_taxonomy_structure'])){
711
- $set = true;
712
- }else {
713
- $set = false;
714
- }
715
- update_option('no_taxonomy_structure', $set);
716
- }
717
- }
718
-
719
- public function setting_section_callback_function() {
720
- ?>
721
- <p><?php _e("Setting permalinks of custom post type.",'cptp');?><br />
722
- <?php _e("The tags you can use is WordPress Structure Tags and '%\"custom_taxonomy_slug\"%'. (e.g. %actors%)",'cptp');?><br />
723
- <?php _e("%\"custom_taxonomy_slug\"% is replaced the taxonomy's term.'.",'cptp');?></p>
724
-
725
- <p><?php _e("Presence of the trailing '/' is unified into a standard permalink structure setting.",'cptp');?>
726
- <?php _e("If you don't entered permalink structure, permalink is configured /%postname%/'.",'cptp');?>
727
- </p>
728
- <?php
729
- }
730
-
731
- public function setting_structure_callback_function( $option ) {
732
- $post_type = str_replace('_structure',"" ,$option);
733
- $slug = get_post_type_object($post_type)->rewrite['slug'];
734
- $with_front = get_post_type_object($post_type)->rewrite['with_front'];
735
-
736
- $value = get_option($option);
737
- if( !$value )
738
- $value = $this->default_structure;
739
-
740
- global $wp_rewrite;
741
- $front = substr( $wp_rewrite->front, 1 );
742
- if( $front and $with_front ) {
743
- $slug = $front.$slug;
744
- }
745
-
746
- echo '<code>'.home_url().'/'.$slug.'</code> <input name="'.$option.'" id="'.$option.'" type="text" class="regular-text code" value="' . $value .'" />';
747
- }
748
-
749
- public function setting_no_tax_structure_callback_function(){
750
- echo '<input name="no_taxonomy_structure" id="no_taxonomy_structure" type="checkbox" value="1" class="code" ' . checked( false, get_option('no_taxonomy_structure'),false) . ' /> ';
751
- $txt = __("If you check,The custom taxonomy's permalinks is <code>%s/post_type/taxonomy/term</code>.","cptp");
752
- printf($txt , home_url());
753
- }
754
-
755
-
756
-
757
- /**
758
- *
759
- * enqueue CSS and JS
760
- * @since 0.8.5
761
- *
762
- */
763
- public function enqueue_css_js() {
764
- wp_enqueue_style('wp-pointer');
765
- wp_enqueue_script('wp-pointer');
766
- }
767
-
768
-
769
-
770
- /**
771
- *
772
- * add js for pointer
773
- * @since 0.8.5
774
- */
775
- public function pointer_js() {
776
- if(!is_network_admin()) {
777
- $dismissed = explode(',', get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ));
778
- if(array_search('cptp_pointer0871', $dismissed) === false){
779
- $content = __("<h3>Custom Post Type Permalinks</h3><p>From <a href='options-permalink.php'>Permalinks</a>, set a custom permalink for each post type.</p>", "cptp");
780
- ?>
781
- <script type="text/javascript">
782
- jQuery(function($) {
783
-
784
- $("#menu-settings .wp-has-submenu").pointer({
785
- content: "<?php echo $content;?>",
786
- position: {"edge":"left","align":"center"},
787
- close: function() {
788
- $.post('admin-ajax.php', {
789
- action:'dismiss-wp-pointer',
790
- pointer: 'cptp_pointer0871'
791
- })
792
-
793
- }
794
- }).pointer("open");
795
- });
796
- </script>
797
- <?php
798
- }
799
- }
800
- }
801
- }
802
-
803
- $custom_post_type_permalinks = new Custom_Post_Type_Permalinks;
804
- $custom_post_type_permalinks = apply_filters('custom_post_type_permalinks', $custom_post_type_permalinks);
805
- $custom_post_type_permalinks->add_hook();
806
- ?>
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: Custom Post Type Permalinks
4
+ Plugin URI: http://www.torounit.com
5
+ Description: Add post archives of custom post type and customizable permalinks.
6
+ Author: Toro_Unit
7
+ Author URI: http://www.torounit.com/plugins/custom-post-type-permalinks/
8
+ Version: 0.9.3.3
9
+ Text Domain: cptp
10
+ License: GPL2 or later
11
+ Domain Path: /language/
12
+ */
13
+
14
+
15
+ /* Copyright 2012 Toro_Unit (email : mail@torounit.com)
16
+
17
+ This program is free software; you can redistribute it and/or modify
18
+ it under the terms of the GNU General Public License as published by
19
+ the Free Software Foundation; either version 2 of the License, or
20
+ (at your option) any later version.
21
+
22
+ This program is distributed in the hope that it will be useful,
23
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
24
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
+ GNU General Public License for more details.
26
+
27
+ You should have received a copy of the GNU General Public License
28
+ along with this program; if not, write to the Free Software
29
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30
+ */
31
+
32
+
33
+
34
+ /**
35
+ *
36
+ * Custom Post Type Permalinks
37
+ *
38
+ *
39
+ */
40
+ class Custom_Post_Type_Permalinks {
41
+
42
+
43
+
44
+
45
+ public $version = "0.9";
46
+
47
+ public $default_structure = '/%postname%/';
48
+
49
+ /**
50
+ *
51
+ * Add Action & filter hooks.
52
+ *
53
+ */
54
+ public function add_hook () {
55
+
56
+ add_action( 'plugins_loaded', array(&$this,'check_version') );
57
+ add_action( 'wp_loaded', array(&$this,'add_archive_rewrite_rules'), 99 );
58
+ add_action( 'wp_loaded', array(&$this,'add_tax_rewrite_rules') );
59
+ add_action( 'wp_loaded', array(&$this, "dequeue_flush_rules"),100);
60
+ add_action( 'parse_request', array(&$this, "parse_request") );
61
+ add_action( 'registered_post_type', array(&$this,'registered_post_type'), 10, 2 );
62
+
63
+
64
+ if(get_option( "permalink_structure") != "") {
65
+ add_filter( 'post_type_link', array(&$this,'post_type_link'), 10, 4 );
66
+ add_filter( 'getarchives_join', array(&$this,'getarchives_join'), 10, 2 ); // [steve]
67
+ add_filter( 'getarchives_where', array(&$this,'getarchives_where'), 10 , 2 );
68
+ add_filter( 'get_archives_link', array(&$this,'get_archives_link'), 20, 1 );
69
+ add_filter( 'term_link', array(&$this,'term_link'), 10, 3 );
70
+ add_filter( 'attachment_link', array(&$this, 'attachment_link'), 20 , 2);
71
+ }
72
+
73
+
74
+ add_action( 'init', array(&$this,'load_textdomain') );
75
+ add_action( 'init', array(&$this, 'update_rules') );
76
+ add_action( 'update_option_cptp_version', array(&$this, 'update_rules') );
77
+ add_action( 'admin_init', array(&$this,'settings_api_init'), 30 );
78
+ add_action( 'admin_enqueue_scripts', array(&$this,'enqueue_css_js') );
79
+ add_action( 'admin_footer', array(&$this,'pointer_js') );
80
+
81
+
82
+ }
83
+
84
+ /**
85
+ *
86
+ * dequeue flush rules
87
+ * @since 0.9
88
+ *
89
+ */
90
+
91
+ public function dequeue_flush_rules () {
92
+ if(get_option("queue_flush_rules")){
93
+ flush_rewrite_rules();
94
+ update_option( "queue_flush_rules", 0 );
95
+
96
+ }
97
+ }
98
+
99
+
100
+ /**
101
+ *
102
+ * dequeue flush rules
103
+ * @since 0.8.6
104
+ *
105
+ */
106
+
107
+ public function check_version() {
108
+ $version = get_option('cptp_version', 0);
109
+ if($version != $this->version) {
110
+ update_option('cptp_version', $this->version);
111
+ }
112
+ }
113
+
114
+ /**
115
+ *
116
+ * Get Custom Taxonomies parents.
117
+ * @version 1.0
118
+ *
119
+ */
120
+ private function get_taxonomy_parents( $id, $taxonomy = 'category', $link = false, $separator = '/', $nicename = false, $visited = array() ) {
121
+ $chain = '';
122
+ $parent = &get_term( $id, $taxonomy, OBJECT, 'raw');
123
+ if ( is_wp_error( $parent ) ) {
124
+ return $parent;
125
+ }
126
+
127
+ if ( $nicename ){
128
+ $name = $parent->slug;
129
+ }else {
130
+ $name = $parent->name;
131
+ }
132
+
133
+ if ( $parent->parent && ( $parent->parent != $parent->term_id ) && !in_array( $parent->parent, $visited ) ) {
134
+ $visited[] = $parent->parent;
135
+ $chain .= $this->get_taxonomy_parents( $parent->parent, $taxonomy, $link, $separator, $nicename, $visited );
136
+ }
137
+
138
+ if ( $link ) {
139
+ $chain .= '<a href="' . get_term_link( $parent->term_id, $taxonomy ) . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $parent->name ) ) . '">'.$name.'</a>' . $separator;
140
+ }else {
141
+ $chain .= $name.$separator;
142
+ }
143
+ return $chain;
144
+ }
145
+
146
+
147
+
148
+ /**
149
+ *
150
+ * Add rewrite rules for archives.
151
+ * @version 1.1
152
+ *
153
+ */
154
+ public function add_archive_rewrite_rules() {
155
+ $post_types = get_post_types( array('_builtin'=>false, 'publicly_queryable'=>true,'show_ui' => true) );
156
+
157
+ foreach ( $post_types as $post_type ):
158
+ if( !$post_type ) {
159
+ continue;
160
+ }
161
+
162
+ $permalink = get_option( $post_type.'_structure' );
163
+ $post_type_obj = get_post_type_object($post_type);
164
+ $slug = $post_type_obj->rewrite['slug'];
165
+ if( !$slug )
166
+ $slug = $post_type;
167
+
168
+ if( $post_type_obj->has_archive ){
169
+ if( is_string( $post_type_obj->has_archive ) ){
170
+ $slug = $post_type_obj->has_archive;
171
+ };
172
+
173
+
174
+ add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&feed=$matches[4]&post_type='.$post_type, 'top' );
175
+ add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/(feed|rdf|rss|rss2|atom)/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&feed=$matches[4]&post_type='.$post_type, 'top' );
176
+ add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/page/?([0-9]{1,})/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&paged=$matches[4]&post_type='.$post_type, 'top' );
177
+ add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&post_type='.$post_type, 'top' );
178
+ add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&feed=$matches[3]&post_type='.$post_type, 'top' );
179
+ add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/(feed|rdf|rss|rss2|atom)/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&feed=$matches[3]&post_type='.$post_type, 'top' );
180
+ add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/page/?([0-9]{1,})/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&paged=$matches[3]&post_type='.$post_type, 'top' );
181
+ add_rewrite_rule( $slug.'/date/([0-9]{4})/([0-9]{1,2})/?$', 'index.php?year=$matches[1]&monthnum=$matches[2]&post_type='.$post_type, 'top' );
182
+ add_rewrite_rule( $slug.'/date/([0-9]{4})/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?year=$matches[1]&feed=$matches[2]&post_type='.$post_type, 'top' );
183
+ add_rewrite_rule( $slug.'/date/([0-9]{4})/(feed|rdf|rss|rss2|atom)/?$', 'index.php?year=$matches[1]&feed=$matches[2]&post_type='.$post_type, 'top' );
184
+ add_rewrite_rule( $slug.'/date/([0-9]{4})/page/?([0-9]{1,})/?$', 'index.php?year=$matches[1]&paged=$matches[2]&post_type='.$post_type, 'top' );
185
+ add_rewrite_rule( $slug.'/date/([0-9]{4})/?$', 'index.php?year=$matches[1]&post_type='.$post_type, 'top' );
186
+ add_rewrite_rule( $slug.'/author/([^/]+)/?$', 'index.php?author_name=$matches[1]&post_type='.$post_type, 'top' );
187
+ }
188
+
189
+
190
+ endforeach;
191
+ }
192
+
193
+ /**
194
+ *
195
+ * registered_post_type
196
+ * ** add rewrite tag for Custom Post Type.
197
+ * @version 1.1
198
+ * @since 0.9
199
+ *
200
+ */
201
+
202
+ public function registered_post_type( $post_type, $args ) {
203
+
204
+ global $wp_post_types, $wp_rewrite, $wp;
205
+
206
+ if( $args->_builtin or !$args->publicly_queryable or !$args->show_ui ){
207
+ return false;
208
+ }
209
+ $permalink = get_option( $post_type.'_structure' );
210
+
211
+ if( !$permalink ) {
212
+ $permalink = $this->default_structure;
213
+ }
214
+
215
+ $permalink = '%'.$post_type.'_slug%'.$permalink;
216
+ $permalink = str_replace( '%postname%', '%'.$post_type.'%', $permalink );
217
+
218
+ add_rewrite_tag( '%'.$post_type.'_slug%', '('.$args->rewrite['slug'].')','post_type='.$post_type.'&slug=' );
219
+
220
+ $taxonomies = get_taxonomies( array("show_ui" => true, "_builtin" => false), 'objects' );
221
+ foreach ( $taxonomies as $taxonomy => $objects ):
222
+ $wp_rewrite->add_rewrite_tag( "%$taxonomy%", '(.+?)', "$taxonomy=" );
223
+ endforeach;
224
+
225
+ $permalink = trim($permalink, "/" );
226
+ $rewrite_args = $args->rewrite;
227
+ $rewrite_args["walk_dirs"] = false;
228
+ add_permastruct( $post_type, $permalink, $rewrite_args);
229
+
230
+ }
231
+
232
+
233
+
234
+
235
+
236
+ /**
237
+ *
238
+ * fix attachment output
239
+ *
240
+ * @version 1.0
241
+ * @since 0.8.2
242
+ *
243
+ */
244
+
245
+ public function attachment_link( $link , $postID ) {
246
+ $post = get_post( $postID );
247
+ if (!$post->post_parent){
248
+ return $link;
249
+ }
250
+ $post_parent = get_post( $post->post_parent );
251
+ $permalink = get_option( $post_parent->post_type.'_structure' );
252
+ $post_type = get_post_type_object( $post_parent->post_type );
253
+
254
+ if( $post_type->_builtin == false ) {
255
+ if(strpos( $permalink, "%postname%" ) < strrpos( $permalink, "%post_id%" ) && strrpos( $permalink, "attachment/" ) === FALSE ){
256
+ $link = str_replace($post->post_name , "attachment/".$post->post_name, $link);
257
+ }
258
+ }
259
+
260
+ return $link;
261
+ }
262
+
263
+
264
+
265
+ /**
266
+ *
267
+ * Fix permalinks output.
268
+ *
269
+ * @param String $post_link
270
+ * @param Object $post 投稿情報
271
+ * @param String $leavename 記事編集画面でのみ渡される
272
+ *
273
+ * @version 2.0
274
+ *
275
+ */
276
+ public function post_type_link( $post_link, $post, $leavename ) {
277
+
278
+ global $wp_rewrite;
279
+ $draft_or_pending = isset( $post->post_status ) && in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft' ) );
280
+ if( $draft_or_pending and !$leavename )
281
+ return $post_link;
282
+
283
+ $post_type = $post->post_type;
284
+ $permalink = $wp_rewrite->get_extra_permastruct( $post_type );
285
+ $permalink = str_replace( '%post_id%', $post->ID, $permalink );
286
+ $permalink = str_replace( '%'.$post_type.'_slug%', get_post_type_object( $post_type )->rewrite['slug'], $permalink );
287
+
288
+
289
+ $parentsDirs = "";
290
+ if( !$leavename ){
291
+ $postId = $post->ID;
292
+ while ($parent = get_post($postId)->post_parent) {
293
+ $parentsDirs = get_post($parent)->post_name."/".$parentsDirs;
294
+ $postId = $parent;
295
+ }
296
+ }
297
+
298
+ $permalink = str_replace( '%'.$post_type.'%', $parentsDirs.'%'.$post_type.'%', $permalink );
299
+
300
+ if( !$leavename ){
301
+ $permalink = str_replace( '%'.$post_type.'%', $post->post_name, $permalink );
302
+ }
303
+
304
+ //%post_id%/attachment/%attachement_name%;
305
+ //画像の編集ページでのリンク
306
+ if( isset($_GET["post"]) && $_GET["post"] != $post->ID ) {
307
+ $parent_structure = trim(get_option( $post->post_type.'_structure' ), "/");
308
+ if( "%post_id%" == $parent_structure or "%post_id%" == array_pop( explode( "/", $parent_structure ) ) ) {
309
+ $permalink = $permalink."/attachment/";
310
+ };
311
+ }
312
+
313
+ $taxonomies = get_taxonomies( array('show_ui' => true),'objects' );
314
+
315
+ //%taxnomomy% -> parent/child
316
+ //運用でケアすべきかも。
317
+ foreach ( $taxonomies as $taxonomy => $objects ) {
318
+ if ( strpos($permalink, "%$taxonomy%") !== false ) {
319
+ $terms = wp_get_post_terms( $post->ID, $taxonomy, array('orderby' => 'term_id'));
320
+ if ( $terms and count($terms) > 1 ) {
321
+ if(reset($terms)->parent == 0){
322
+
323
+ $keys = array_keys($terms);
324
+ $term = $terms[$keys[1]]->slug;
325
+ if ( $terms[$keys[0]]->term_id == $terms[$keys[1]]->parent ) {
326
+ $term = $this->get_taxonomy_parents( $terms[$keys[1]]->parent,$taxonomy, false, '/', true ) . $term;
327
+ }
328
+ }else{
329
+ $keys = array_keys($terms);
330
+ $term = $terms[$keys[0]]->slug;
331
+ if ( $terms[$keys[1]]->term_id == $terms[$keys[0]]->parent ) {
332
+ $term = $this->get_taxonomy_parents( $terms[$keys[0]]->parent,$taxonomy, false, '/', true ) . $term;
333
+ }
334
+ }
335
+ }else if( $terms ){
336
+
337
+ $term_obj = array_shift($terms);
338
+ $term = $term_obj->slug;
339
+
340
+ if(isset($term_obj->parent) and $term_obj->parent != 0) {
341
+ $term = $this->get_taxonomy_parents( $term_obj->parent,$taxonomy, false, '/', true ) . $term;
342
+ }
343
+ }
344
+
345
+ if( isset($term) ) {
346
+ $permalink = str_replace( "%$taxonomy%", $term, $permalink );
347
+ }
348
+ }
349
+ }
350
+
351
+ $user = get_userdata( $post->post_author );
352
+ if(isset($user->user_nicename)) {
353
+ $permalink = str_replace( "%author%", $user->user_nicename, $permalink );
354
+ }
355
+
356
+ $post_date = strtotime( $post->post_date );
357
+ $permalink = str_replace( "%year%", date("Y",$post_date), $permalink );
358
+ $permalink = str_replace( "%monthnum%", date("m",$post_date), $permalink );
359
+ $permalink = str_replace( "%day%", date("d",$post_date), $permalink );
360
+ $permalink = str_replace( "%hour%", date("H",$post_date), $permalink );
361
+ $permalink = str_replace( "%minute%", date("i",$post_date), $permalink );
362
+ $permalink = str_replace( "%second%", date("s",$post_date), $permalink );
363
+
364
+
365
+ $permalink = home_url()."/".user_trailingslashit( $permalink );
366
+ $permalink = str_replace("//", "/", $permalink);
367
+ $permalink = str_replace(":/", "://", $permalink);
368
+ return $permalink;
369
+ }
370
+
371
+
372
+
373
+ /**
374
+ *
375
+ * wp_get_archives fix for custom post
376
+ * Ex:wp_get_archives('&post_type='.get_query_var( 'post_type' ));
377
+ * @version 2.0
378
+ *
379
+ */
380
+
381
+ public $get_archives_where_r;
382
+
383
+ // function modified by [steve]
384
+ public function getarchives_where( $where, $r ) {
385
+ $this->get_archives_where_r = $r;
386
+ if ( isset($r['post_type']) ) {
387
+ $where = str_replace( '\'post\'', '\'' . $r['post_type'] . '\'', $where );
388
+ }
389
+
390
+ if(isset($r['taxonomy']) && is_array($r['taxonomy']) ){
391
+ global $wpdb;
392
+ $where = $where . " AND $wpdb->term_taxonomy.taxonomy = '".$r['taxonomy']['name']."' AND $wpdb->term_taxonomy.term_id = '".$r['taxonomy']['termid']."'";
393
+ }
394
+
395
+ return $where;
396
+ }
397
+
398
+
399
+
400
+ //function added by [steve]
401
+ /**
402
+ *
403
+ * get_archive_join
404
+ * @author Steve
405
+ * @since 0.8
406
+ * @version 1.0
407
+ *
408
+ *
409
+ */
410
+ public function getarchives_join( $join, $r ) {
411
+ global $wpdb;
412
+ $this->get_archives_where_r = $r;
413
+ if(isset($r['taxonomy']) && is_array($r['taxonomy']) )
414
+ $join = $join . " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
415
+
416
+ return $join;
417
+ }
418
+
419
+
420
+
421
+ /**
422
+ *
423
+ * get_arcihves_link
424
+ * @version 2.1
425
+ *
426
+ */
427
+ public function get_archives_link( $link ) {
428
+ if(!isset($this->get_archives_where_r['post_type'])) {
429
+ return $link;
430
+ }
431
+ $c = isset($this->get_archives_where_r['taxonomy']) && is_array($this->get_archives_where_r['taxonomy']) ? $this->get_archives_where_r['taxonomy'] : ""; //[steve]
432
+ $t = $this->get_archives_where_r['post_type'];
433
+
434
+
435
+ $this->get_archives_where_r['post_type'] = isset($this->get_archives_where_r['post_type_slug']) ? $this->get_archives_where_r['post_type_slug'] : $t; // [steve] [*** bug fixing]
436
+
437
+ if (isset($this->get_archives_where_r['post_type']) and $this->get_archives_where_r['type'] != 'postbypost'){
438
+ $blog_url = rtrim( get_bloginfo("url") ,'/');
439
+
440
+ //remove .ext
441
+ $str = preg_replace("/\.[a-z,_]*/","",get_option("permalink_structure"));
442
+
443
+ if($str = rtrim( preg_replace("/%[a-z,_]*%/","",$str) ,'/')) { // /archive/%post_id%
444
+ $ret_link = str_replace($str, '/'.'%link_dir%', $link);
445
+ }else{
446
+ $blog_url = preg_replace('/https?:\/\//', '', $blog_url);
447
+ $ret_link = str_replace($blog_url,$blog_url.'/'.'%link_dir%',$link);
448
+ }
449
+
450
+ $post_type = get_post_type_object( $this->get_archives_where_r['post_type'] );
451
+ if(empty($c) ){ // [steve]
452
+ if(isset( $post_type->rewrite["slug"] )) {
453
+ $link_dir = $post_type->rewrite["slug"];
454
+ }
455
+ else{
456
+ $link_dir = $this->get_archives_where_r['post_type'];
457
+ }
458
+ }
459
+ else{ // [steve]
460
+ $c['name'] = ($c['name'] == 'category' && get_option('category_base')) ? get_option('category_base') : $c['name'];
461
+ $link_dir = $post_type->rewrite["slug"]."/".$c['name']."/".$c['termslug'];
462
+ }
463
+
464
+ if(!strstr($link,'/date/')){
465
+ $link_dir = $link_dir .'/date';
466
+ }
467
+
468
+ $ret_link = str_replace('%link_dir%',$link_dir,$ret_link);
469
+ }else {
470
+ $ret_link = $link;
471
+ }
472
+ $this->get_archives_where_r['post_type'] = $t; // [steve] reverting post_type to previous value
473
+
474
+ return $ret_link;
475
+ }
476
+
477
+
478
+
479
+ /**
480
+ *
481
+ * Add rewrite rules for custom taxonomies.
482
+ * @since 0.6
483
+ * @version 2.1
484
+ *
485
+ */
486
+ public function add_tax_rewrite_rules() {
487
+ if(get_option('no_taxonomy_structure')) {
488
+ return false;
489
+ }
490
+
491
+
492
+ global $wp_rewrite;
493
+ $taxonomies = get_taxonomies(array( '_builtin' => false));
494
+ $taxonomies['category'] = 'category';
495
+
496
+ if(empty($taxonomies)) {
497
+ return false;
498
+ }
499
+
500
+ foreach ($taxonomies as $taxonomy) :
501
+ $taxonomyObject = get_taxonomy($taxonomy);
502
+ $post_types = $taxonomyObject->object_type;
503
+
504
+ foreach ($post_types as $post_type):
505
+ $post_type_obj = get_post_type_object($post_type);
506
+ $slug = $post_type_obj->rewrite['slug'];
507
+ if(!$slug) {
508
+ $slug = $post_type;
509
+ }
510
+
511
+ if(is_string($post_type_obj->has_archive)) {
512
+ $slug = $post_type_obj->has_archive;
513
+ };
514
+
515
+ if ( $taxonomy == 'category' ){
516
+ $taxonomypat = ($cb = get_option('category_base')) ? $cb : $taxonomy;
517
+ $tax = 'category_name';
518
+ } else {
519
+ // Edit by [Xiphe]
520
+ if (isset($taxonomyObject->rewrite['slug'])) {
521
+ $taxonomypat = $taxonomyObject->rewrite['slug'];
522
+ } else {
523
+ $taxonomypat = $taxonomy;
524
+ }
525
+ // [Xiphe] stop
526
+
527
+ $tax = $taxonomy;
528
+ }
529
+
530
+
531
+ //add taxonomy slug
532
+ add_rewrite_rule( $slug.'/'.$taxonomypat.'/(.+?)/page/?([0-9]{1,})/?$', 'index.php?'.$tax.'=$matches[1]&paged=$matches[2]', 'top' );
533
+ add_rewrite_rule( $slug.'/'.$taxonomypat.'/(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?'.$tax.'=$matches[1]&feed=$matches[2]', 'top' );
534
+ add_rewrite_rule( $slug.'/'.$taxonomypat.'/(.+?)/(feed|rdf|rss|rss2|atom)/?$', 'index.php?'.$tax.'=$matches[1]&feed=$matches[2]', 'top' );
535
+ add_rewrite_rule( $slug.'/'.$taxonomypat.'/(.+?)/?$', 'index.php?'.$tax.'=$matches[1]', 'top' ); // modified by [steve] [*** bug fixing]
536
+
537
+ // below rules were added by [steve]
538
+ add_rewrite_rule( $taxonomypat.'/(.+?)/date/([0-9]{4})/([0-9]{1,2})/?$', 'index.php?'.$tax.'=$matches[1]&year=$matches[2]&monthnum=$matches[3]&post_type='.$post_type, 'top' );
539
+ add_rewrite_rule( $taxonomypat.'/(.+?)/date/([0-9]{4})/([0-9]{1,2})/page/?([0-9]{1,})/?$', 'index.php?'.$tax.'=$matches[1]&year=$matches[2]&monthnum=$matches[3]&paged=$matches[4]&post_type='.$post_type, 'top' );
540
+ add_rewrite_rule( $slug.'/'.$taxonomypat.'/(.+?)/date/([0-9]{4})/([0-9]{1,2})/?$', 'index.php?'.$tax.'=$matches[1]&year=$matches[2]&monthnum=$matches[3]&post_type='.$post_type, 'top' );
541
+ add_rewrite_rule( $slug.'/'.$taxonomypat.'/(.+?)/date/([0-9]{4})/([0-9]{1,2})/page/?([0-9]{1,})/?$', 'index.php?'.$tax.'=$matches[1]&year=$matches[2]&monthnum=$matches[3]&paged=$matches[4]&post_type='.$post_type, 'top' );
542
+
543
+ endforeach;
544
+ endforeach;
545
+ }
546
+
547
+
548
+
549
+
550
+ /**
551
+ *
552
+ * Fix taxonomy link outputs.
553
+ * @since 0.6
554
+ * @version 1.0
555
+ *
556
+ */
557
+ public function term_link( $termlink, $term, $taxonomy ) {
558
+ if( get_option('no_taxonomy_structure') ) {
559
+ return $termlink;
560
+ }
561
+
562
+ $taxonomy = get_taxonomy($taxonomy);
563
+ if( $taxonomy->_builtin )
564
+ return $termlink;
565
+
566
+ if( empty($taxonomy) )
567
+ return $termlink;
568
+
569
+ $wp_home = rtrim( home_url(), '/' );
570
+
571
+ $post_type = $taxonomy->object_type[0];
572
+ $slug = get_post_type_object($post_type)->rewrite['slug'];
573
+ $with_front = get_post_type_object($post_type)->rewrite['with_front'];
574
+
575
+ //$termlink = str_replace( $term->slug.'/', $this->get_taxonomy_parents( $term->term_id,$taxonomy->name, false, '/', true ), $termlink );
576
+
577
+ //拡張子を削除。
578
+ $str = array_shift(explode(".", get_option("permalink_structure")));
579
+ $str = rtrim( preg_replace( "/%[a-z_]*%/", "" ,$str) ,'/' );//remove with front
580
+ $termlink = str_replace($str."/", "/", $termlink );
581
+
582
+ if( $with_front === false ) {
583
+ $str = "";
584
+ }
585
+ $slug = $str."/".$slug;
586
+
587
+ $termlink = str_replace( $wp_home, $wp_home.$slug, $termlink );
588
+ $termlink = str_replace( $term->slug.'/', $this->get_taxonomy_parents( $term->term_id,$taxonomy->name, false, '/', true ), $termlink );
589
+ return $termlink;
590
+ }
591
+
592
+ /**
593
+ *
594
+ * Fix taxonomy = parent/child => taxonomy => child
595
+ * @since 0.9.3
596
+ *
597
+ */
598
+ public function parse_request($obj) {
599
+ $taxes = get_taxonomies(array( '_builtin' => false));
600
+ foreach ($taxes as $key => $tax) {
601
+ if(isset($obj->query_vars[$tax])) {
602
+ if(strpos( $obj->query_vars[$tax] ,"/") !== false ) {
603
+ $obj->query_vars[$tax] = array_pop(explode("/", $obj->query_vars[$tax]));
604
+ }
605
+ }
606
+ }
607
+ }
608
+
609
+
610
+
611
+ /**
612
+ *
613
+ * load textdomain
614
+ * @since 0.6.2
615
+ *
616
+ */
617
+ public function load_textdomain() {
618
+ load_plugin_textdomain('cptp',false,'custom-post-type-permalinks/language');
619
+ }
620
+
621
+
622
+
623
+ /**
624
+ *
625
+ * Add hook flush_rules
626
+ * @since 0.7.9
627
+ *
628
+ */
629
+ public function update_rules() {
630
+
631
+ $post_types = get_post_types( array('_builtin'=>false, 'publicly_queryable'=>true, 'show_ui' => true) );
632
+ $type_count = count($post_types);
633
+ $i = 0;
634
+ foreach ($post_types as $post_type):
635
+ add_action('update_option_'.$post_type.'_structure',array(&$this,'queue_flush_rules'),10,2);
636
+ endforeach;
637
+ add_action('update_option_no_taxonomy_structure',array(&$this,'queue_flush_rules'),10,2);
638
+ }
639
+
640
+
641
+
642
+ /**
643
+ * Flush rules
644
+ *
645
+ * @since 0.7.9
646
+ *
647
+ */
648
+
649
+ public function queue_flush_rules(){
650
+ update_option( "queue_flush_rules", 1 );
651
+ }
652
+
653
+
654
+
655
+ /**
656
+ *
657
+ * Setting Init
658
+ * @since 0.7
659
+ *
660
+ */
661
+ public function settings_api_init() {
662
+ add_settings_section('cptp_setting_section',
663
+ __("Permalink Setting for custom post type",'cptp'),
664
+ array(&$this,'setting_section_callback_function'),
665
+ 'permalink'
666
+ );
667
+
668
+ $post_types = get_post_types( array('_builtin'=>false, 'publicly_queryable'=>true, 'show_ui' => true) );
669
+ foreach ($post_types as $post_type):
670
+ if(isset($_POST['submit']) and isset($_POST['_wp_http_referer'])){
671
+ if( strpos($_POST['_wp_http_referer'],'options-permalink.php') !== FALSE ) {
672
+
673
+ $structure = trim(esc_attr($_POST[$post_type.'_structure']));#get setting
674
+
675
+ #default permalink structure
676
+ if( !$structure )
677
+ $structure = $this->default_structure;
678
+
679
+ $structure = str_replace('//','/','/'.$structure);# first "/"
680
+
681
+ #last "/"
682
+ $lastString = substr(trim(esc_attr($_POST['permalink_structure'])),-1);
683
+ $structure = rtrim($structure,'/');
684
+
685
+ if ( $lastString == '/')
686
+ $structure = $structure.'/';
687
+
688
+ update_option($post_type.'_structure', $structure );
689
+ }
690
+ }
691
+
692
+ add_settings_field($post_type.'_structure',
693
+ $post_type,
694
+ array(&$this,'setting_structure_callback_function'),
695
+ 'permalink',
696
+ 'cptp_setting_section',
697
+ $post_type.'_structure'
698
+ );
699
+
700
+ register_setting('permalink',$post_type.'_structure');
701
+ endforeach;
702
+
703
+ add_settings_field(
704
+ 'no_taxonomy_structure',
705
+ __("Use custom permalink of custom taxonomy archive.",'cptp'),
706
+ array(&$this,'setting_no_tax_structure_callback_function'),
707
+ 'permalink',
708
+ 'cptp_setting_section'
709
+ );
710
+
711
+ register_setting('permalink','no_taxonomy_structure');
712
+
713
+ if(isset($_POST['submit']) && isset($_POST['_wp_http_referer']) && strpos($_POST['_wp_http_referer'],'options-permalink.php') !== FALSE ) {
714
+
715
+ if(!isset($_POST['no_taxonomy_structure'])){
716
+ $set = true;
717
+ }else {
718
+ $set = false;
719
+ }
720
+ update_option('no_taxonomy_structure', $set);
721
+ }
722
+ }
723
+
724
+ public function setting_section_callback_function() {
725
+ ?>
726
+ <p><?php _e("Setting permalinks of custom post type.",'cptp');?><br />
727
+ <?php _e("The tags you can use is WordPress Structure Tags and '%\"custom_taxonomy_slug\"%'. (e.g. %actors%)",'cptp');?><br />
728
+ <?php _e("%\"custom_taxonomy_slug\"% is replaced the taxonomy's term.'.",'cptp');?></p>
729
+
730
+ <p><?php _e("Presence of the trailing '/' is unified into a standard permalink structure setting.",'cptp');?>
731
+ <?php _e("If you don't entered permalink structure, permalink is configured /%postname%/'.",'cptp');?>
732
+ </p>
733
+ <?php
734
+ }
735
+
736
+ public function setting_structure_callback_function( $option ) {
737
+ $post_type = str_replace('_structure',"" ,$option);
738
+ $slug = get_post_type_object($post_type)->rewrite['slug'];
739
+ $with_front = get_post_type_object($post_type)->rewrite['with_front'];
740
+
741
+ $value = get_option($option);
742
+ if( !$value )
743
+ $value = $this->default_structure;
744
+
745
+ global $wp_rewrite;
746
+ $front = substr( $wp_rewrite->front, 1 );
747
+ if( $front and $with_front ) {
748
+ $slug = $front.$slug;
749
+ }
750
+
751
+ echo '<code>'.home_url().'/'.$slug.'</code> <input name="'.$option.'" id="'.$option.'" type="text" class="regular-text code" value="' . $value .'" />';
752
+ }
753
+
754
+ public function setting_no_tax_structure_callback_function(){
755
+ echo '<input name="no_taxonomy_structure" id="no_taxonomy_structure" type="checkbox" value="1" class="code" ' . checked( false, get_option('no_taxonomy_structure'),false) . ' /> ';
756
+ $txt = __("If you check,The custom taxonomy's permalinks is <code>%s/post_type/taxonomy/term</code>.","cptp");
757
+ printf($txt , home_url());
758
+ }
759
+
760
+
761
+
762
+ /**
763
+ *
764
+ * enqueue CSS and JS
765
+ * @since 0.8.5
766
+ *
767
+ */
768
+ public function enqueue_css_js() {
769
+ wp_enqueue_style('wp-pointer');
770
+ wp_enqueue_script('wp-pointer');
771
+ }
772
+
773
+
774
+
775
+ /**
776
+ *
777
+ * add js for pointer
778
+ * @since 0.8.5
779
+ */
780
+ public function pointer_js() {
781
+ if(!is_network_admin()) {
782
+ $dismissed = explode(',', get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ));
783
+ if(array_search('cptp_pointer0871', $dismissed) === false){
784
+ $content = __("<h3>Custom Post Type Permalinks</h3><p>From <a href='options-permalink.php'>Permalinks</a>, set a custom permalink for each post type.</p>", "cptp");
785
+ ?>
786
+ <script type="text/javascript">
787
+ jQuery(function($) {
788
+
789
+ $("#menu-settings .wp-has-submenu").pointer({
790
+ content: "<?php echo $content;?>",
791
+ position: {"edge":"left","align":"center"},
792
+ close: function() {
793
+ $.post('admin-ajax.php', {
794
+ action:'dismiss-wp-pointer',
795
+ pointer: 'cptp_pointer0871'
796
+ })
797
+
798
+ }
799
+ }).pointer("open");
800
+ });
801
+ </script>
802
+ <?php
803
+ }
804
+ }
805
+ }
806
+ }
807
+
808
+ $custom_post_type_permalinks = new Custom_Post_Type_Permalinks;
809
+ $custom_post_type_permalinks = apply_filters('custom_post_type_permalinks', $custom_post_type_permalinks);
810
+ $custom_post_type_permalinks->add_hook();
811
+ ?>
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: Toro_Unit
3
  Tags: permalink,permalinks,custom post type,custom taxonomy,cms
4
  Requires at least: 3.4
5
  Tested up to: 3.6
6
- Stable tag: 0.9.3.2
7
 
8
  Lets you edit the permalink of custom post type.
9
 
@@ -13,9 +13,9 @@ Custom Post Type Permalinks lets you edit the permalink structure of custom post
13
 
14
  Change custom taxonomy archive's permalink to "example.org/post_type/taxonomy_name/term_slug". Can disable this fix.
15
 
16
- [This Plugin published on GitHub.](https://github.com/Toro-Unit/custom-post-type-permalinks)
17
 
18
- Donation: Please send Amazon Gift to donate[at]torounit.com.
19
 
20
  = Translators =
21
  * Japanese(ja) - [Toro_Unit](http://www.torounit.com/)
@@ -24,27 +24,34 @@ Donation: Please send Amazon Gift to donate[at]torounit.com.
24
 
25
  == Installation ==
26
 
27
- *. Download the custom-post-type-permalinks.zip file to your computer.
28
- *. Unzip the file.
29
- *. Upload the `custom-post-type-permalinks` directory to your `/wp-content/plugins/` directory.
30
- *. Activate the plugin through the 'Plugins' menu in WordPress.
 
 
31
 
32
  That's it. You can access the permalinks setting by going to *Settings -> Permalinks*.
33
 
34
 
35
  == Screenshots ==
36
 
37
- *. screenshot-1.png
 
 
 
 
 
 
 
38
 
39
 
40
- == Changelog ==
41
-
42
  = 0.9.3.2 =
43
  * wp_get_archives Bug Fix.
44
 
45
  = 0.9.3.1 =
46
  * Tested 3.6
47
- *Bug Fix.
48
 
49
 
50
  = 0.9.3 =
3
  Tags: permalink,permalinks,custom post type,custom taxonomy,cms
4
  Requires at least: 3.4
5
  Tested up to: 3.6
6
+ Stable tag: 0.9.3.3
7
 
8
  Lets you edit the permalink of custom post type.
9
 
13
 
14
  Change custom taxonomy archive's permalink to "example.org/post_type/taxonomy_name/term_slug". Can disable this fix.
15
 
16
+ [This Plugin published on GitHub.](https://github.com/torounit/custom-post-type-permalinks)
17
 
18
+ Donation: Please send amazon.co.jp Gift to donate[at]torounit.com.
19
 
20
  = Translators =
21
  * Japanese(ja) - [Toro_Unit](http://www.torounit.com/)
24
 
25
  == Installation ==
26
 
27
+
28
+ 1. Download the custom-post-type-permalinks.zip file to your computer.
29
+ 1. Unzip the file.
30
+ 1. Upload the `custom-post-type-permalinks` directory to your `/wp-content/plugins/` directory.
31
+ 1. Activate the plugin through the 'Plugins' menu in WordPress.
32
+
33
 
34
  That's it. You can access the permalinks setting by going to *Settings -> Permalinks*.
35
 
36
 
37
  == Screenshots ==
38
 
39
+ * screenshot-1.png
40
+
41
+
42
+ == Changelog ==
43
+
44
+ = 0.9.3.3 =
45
+ * Fix Override Page Permalink Bug.
46
+ * has_archive Bug Fix.
47
 
48
 
 
 
49
  = 0.9.3.2 =
50
  * wp_get_archives Bug Fix.
51
 
52
  = 0.9.3.1 =
53
  * Tested 3.6
54
+ * Bug Fix.
55
 
56
 
57
  = 0.9.3 =