Ticket #6110: series-taxonomy.php.txt

File series-taxonomy.php.txt, 32.3 kB (added by nerrad, 9 months ago)

Plugin file that contains the rewrite code.

Line 
1 <?php
2 /* This file is for all the Organize Series related Term Queries and "tags".  I just wanted to clean up the main plugin file a bit!
3 Please note:  I followed various WP core files for structuring code which made it easier than it could have been.  So I must give credit where credit is due!
4  */
5 //these defines need to be moved to the orgSeries.php
6  define('SERIES_QUERYVAR', 'series');  // get/post variable name for querying series from WP
7  define('SERIES_URL', 'series'); //URL to use when querying series
8  define('SERIES_TEMPLATE', 'series.php'); //template file to use for displaying series queries.
9  define('SERIES_SEARCHURL','search'); //local search URL (from mod_rewrite_rules)
10  define('SERIES_PART_KEY', 'series_part'); //the default key for the Custom Field that distinguishes what part a post is in the series it belongs to.
11  define('SERIES_REWRITERULES','1'); //flag to determine if plugin can change WP rewrite rules.
12  
13 /*utitlity functions -- perhaps add to their own file for better organization? */
14
15 function _usort_series_by_part($a, $b) {
16         if ($a['part'] > $b['part'] )
17                 return 1;
18         elseif ( $a['part'] < $b['part'] )
19                 return -1;
20         else
21                 return 0;
22         }
23
24        
25 //This function is used to create an array of posts in a series including the order the posts are in the series.  Then it will sort the array so it is keyed in the order the posts are in.  Will return the array.
26 function get_series_order ($posts, $postid = 0, $skip = TRUE) {
27         if (!isset($posts)) return false; //don't have the posts object so can't do anything.
28        
29         if ( !is_array( $posts ) )
30                 $posts = array($posts);
31                
32         $series_posts = array();
33         $key = 0;
34        
35         foreach ($posts as $spost) {
36                 if (array_key_exists('object_id', $spost)) {
37                         $spost_id = $spost['object_id'];
38                 } else {
39                         $spost_id = $spost;
40                 }
41                
42                 if ($skip && $spost_id == $postid) continue;
43                         $currentpart = get_post_meta($spost_id, SERIES_PART_KEY, true);
44                         $series_posts[$key]['id'] = $spost_id;
45                         $series_posts[$key]['part'] = $currentpart;
46                         $key++;
47                 }
48        
49         if (count($series_posts) > 1)
50                 usort( $series_posts, '_usort_series_by_part' );
51                
52         return $series_posts;
53 }
54  
55  /* functions referenced by other files */
56 function &get_series($args = '') {
57         global $wpdb;
58        
59         $key = md5( serialize($args) );
60         if ( $cache = wp_cache_get('get_series','series') )
61                 if ( isset( $cache[ $key ] ) )
62                         return apply_filters('get_series', $cache[$key],$args);
63                        
64         $series = get_terms('series', $args);
65        
66         if ( empty($series) )
67                 return array();
68                
69         $cache[ $key ] = $series;
70         wp_cache_set( 'get_series', $cache, 'series' );
71        
72         $series = apply_filters('get_series', $series, $args);
73         return $series;
74 }
75        
76 function &get_orgserial($orgserial, $output = OBJECT, $filter = 'raw') {
77                 return get_term($orgserial, 'series', $output, $filter);
78 }
79
80 //permalinks , rewrite rules etc.//
81 function get_series_permastruct() {
82         global $wp_rewrite;
83        
84         if (empty($wp_rewrite->permalink_structure)) {
85                 $series_structure = '';
86                 return false;
87         }
88        
89         $series_token = '%' . SERIES_QUERYVAR . '%';
90         $series_structure = $wp_rewrite->front . SERIES_QUERYVAR . "/$series_token";
91         return $series_structure;
92 }
93
94 function series_createRewriteRules($rules) {
95         global $wp_rewrite;
96        
97         $series_token = '%' . SERIES_QUERYVAR . '%';
98         $wp_rewrite->add_rewrite_tag($series_token, '(.+)', SERIES_QUERYVAR . '=');
99        
100         //without trailing slash
101         $series_structure = $wp_rewrite->root . SERIES_QUERYVAR . "/$series_token";
102         $rewrite = $wp_rewrite->generate_rewrite_rules($series_structure);
103         //return $series_structure;
104         return ( $rules + $rewrite );
105 }
106
107 function series_init() {
108         global $wp_rewrite;
109        
110         if (isset($wp_rewrite) && $wp_rewrite->using_permalinks()) {
111                 define('SERIES_REWRITEON', '1');  //pretty permalinks please!
112         } else {
113                 define('SERIES_REWRITEON', '0');  //old school links
114         }
115        
116        
117         //generate rewrite rules for series queries
118        
119         if (SERIES_REWRITEON && SERIES_REWRITERULES)
120                 add_filter('rewrite_rules_array', 'series_createRewriteRules');
121                
122         //setting up the series_toc_page redirect
123         $settings = get_option('org_series_options');
124         $series_toc_url = $settings['series_toc_url'];
125         if ($series_toc_url && (strpos($_SERVER['REQUEST_URI'], $series_toc_url) === 0) && (strlen($_SERVER['REQUEST_URI']) == strlen($series_toc_url))) {
126                 status_header(200);
127                 add_filter('request', 'orgSeries_request');
128                 add_action('parse_query', 'orgSeries_parse_query');
129                 add_action('template_redirect', 'orgSeries_toc_template');
130         }
131         //$wp_rewrite->flush_rules();  //TODO: (NEEDS TESTING) I THINK THIS MIGHT MAKE IT SO USERS DON'T HAVE TO UPDATE THE PERMALINKS MANUALLY.  Probably should be added to the plugin_activation hook.
132 }
133
134 function orgSeries_parse_query($wp_query) {
135         $wp_query->is_404 = false;
136 }
137
138 function orgSeries_request($query_vars) {
139         $query_vars['error'] = false;
140         return $query_vars;
141 }
142
143 function orgSeries_toc_template() {
144         if (file_exists(TEMPLATEPATH . '/seriestoc.php')) {
145                 $template =  TEMPLATEPATH . '/seriestoc.php';
146         } else {
147                 $template = ABSPATH . 'wp-content/plugins/orgSeries/seriestoc.php';
148         }
149        
150         if ($template) {
151                 load_template($template);
152                 exit;
153         }
154         return;
155 }
156 add_action('init', 'series_init');
157
158
159 /* ---------- SERIES TEMPLATE TAGS (maybe add to a series-template.php file?) --------------------------*/
160 //url constructor/function template tags.
161 function get_series_link( $series_id ) {
162         $series_token = '%' . SERIES_QUERYVAR . '%';
163         $serieslink = get_series_permastruct();
164        
165         $series = &get_term($series_id, 'series');
166         if (is_wp_error( $series ) )
167                 return $series;
168         $slug = $series->slug;
169         $id = $series->term_id;
170        
171         if ( empty($serieslink) ) {
172                 $file = get_option('home') . '/';
173                 $serieslink = $file . '?series=' . $id;
174         } else {
175                 $serieslink = str_replace($series_token, $slug, $serieslink);
176                 $serieslink = get_settings('home') . user_trailingslashit($serieslink, 'series');
177         }
178         return $serieslink;
179         //return apply_filters('series_link', $serieslink, $series_id);
180 }
181        
182 function get_the_series( $id = false ) {
183         global $post, $tem_cache, $blog_id;
184        
185         $id = (int) $id;
186        
187         if ( !$id )
188                 $id = (int) $post->ID;
189        
190         $series = get_object_term_cache($id, 'series');
191        
192         if (false === $series )
193                 $series = wp_get_object_terms($id, 'series');
194                
195         $series = apply_filters('get_the_series', $series); //adds a new filter for users to hook into
196
197         if ( !empty($series) )
198                 usort($series, '_usort_terms_by_name');
199        
200         return $series;
201 }
202
203 function get_the_series_by_ID( $series_ID ) {
204         $series_ID = (int) $series_ID;
205         $series = &get_orgserial($series_ID);
206         if ( is_wp_error( $series ) )
207                 return $series;
208         return $series->name;
209 }
210
211 function get_the_series_list( $before = '', $sep = '', $after = '') { //This prepares a display lists of all series associated with a particular post and can choose the surrounding tags. Probably should modify this so the surrounding tags can be set in options? This particular function only returns the values.  the_series() will echo the values by default (and calls this function).
212         $series = get_the_series();
213
214         if ( empty( $series ) )
215                 return false;
216        
217         $series_list = $before;
218         foreach ( $series as $orgSerial ) {
219                 $link = get_series_link($orgSerial->term_id);
220                 if  ( is_wp_error( $link ) )
221                         return $link;
222                 $series_links[] = '<a href="' . $link . '" rel="series">' . $orgSerial->name . '</a>';
223         }
224        
225         $series_links = join( $sep, $series_links);
226         $series_links = apply_filters ( 'the_series', $series_links );
227         $series_list .= $tag_links;
228        
229         $series_list .= $after;
230        
231         return $series_list;
232 }
233
234 function the_series( $before = 'Series: ', $sep = ', ', $after = '') { //This function will echo the results from get_the_series_list with the modification of what shows up surrounding each series
235         $return = get_the_series_list($before, $sep, $after);
236         if ( is_wp_error( $return ) )
237                 return false;
238         else
239                 echo $return;
240 }
241
242 function in_series( $series_term ) { //check if the current post is in the given series
243         global $post, $blog_id;
244        
245         $series = get_object_term_cache($post->ID, 'series');
246         if ( false === $series )
247                 $series = wp_get_object_terms($post->ID, 'series');
248         if ( array_key_exists($series_term, $series))
249                 return true;
250         else
251                 return false;
252 }
253
254 function get_series_name($series_id) {
255         $series_id = (int) $series_id;
256         $series = get_orgserial($series_id);
257         return $series->name;
258 }
259
260 function the_series_title($series_id=0, $linked=TRUE, $display=FALSE) {
261         if( 0==$series_id )
262                 return false;
263        
264         $series_id = (int) $series_id ;
265        
266         if ( !empty($series_id) ) {
267                 $series_name = get_series_name($series_id);
268                 if ( is_wp_error( $series_name ) )
269                         return false;
270                 $prefix = '';
271                 $suffix = '';
272                
273                 if ( !empty($series_name) ) {
274                         if ( $linked ) {
275                                 $series_link = get_series_link($series_id);
276                                 $prefix = '<a href="' . $series_link . '" title="series-' . $series_id . '">';
277                                 $suffix = '</a>';
278                         }
279                        
280                         $result = $prefix . $series_name . $suffix;
281                         if ( $display )
282                                 echo $result;
283                         else
284                                 return $result;
285                 }
286         }
287         return false;
288 }
289
290 function series_description($series_id = 0) {
291         global $series;
292         if ( !$series_id )
293                 $series_id = $series;
294                
295         return get_term_field('description', $series_id, 'series');
296 }
297
298 function series_post_title($post_ID, $linked=TRUE) {
299         global $post;
300         if (!isset($post_ID))
301                 $post_ID = (int)$post->ID;
302         $title = get_the_title($post_ID);
303         if ($linked) {
304                 $link = get_permalink($post_ID);
305                 $return = '<a href="' . $link . '" title="' . $title . '">' . $title . '</a>';
306         } else {
307                 $return = $title;
308         }
309         return $return;
310 }
311                
312
313 /** Replaces tokens (set in orgSeries options) with the relevant values **/
314 /** NOTE: %postcontent% is NOT replaced with this function...it happens in the content filter function **/
315 function token_replace($replace, $referral = 'other', $id = 0) {
316         global $post;
317         $p_id = $post->ID;
318         $settings = get_option('org_series_options');
319         if ( 'post-list' == $referral  ) {
320                 $ser_width = $settings['series_icon_width_post_page'];
321                  } elseif ( 'latest_series' == $referral ) {
322                  $ser_width = $settings['series_icon_width_latest_series'];
323                 } else {
324                  $ser_width = $settings['series_icon_width_series_page'];
325                  }
326         if ( 'series-toc' == $referral  || 'latest_series' == $referral ) {
327                 $replace = str_replace('%total_posts_in_series%', wp_postlist_count($id), $replace);
328         } else {
329                 $replace = str_replace('%total_posts_in_series%', wp_postlist_count(), $replace);
330         }
331                
332         if( stristr($replace, '%series_icon%') )
333         $replace = str_replace('%series_icon%', get_series_icon('fit_width=' .  $ser_width . '&link=0&series=' . $id . '&display=0'), $replace);
334         if( stristr($replace, '%series_icon_linked%') )
335         $replace = str_replace('%series_icon_linked%', get_series_icon('fit_width= ' . $ser_width . '&series=' . $id . '&display=0'), $replace);
336         if( stristr($replace, '%series_title%') )
337         $replace = str_replace('%series_title%', the_series_title($id, FALSE), $replace);
338         if( stristr($replace, '%series_title_linked%') )
339         $replace = str_replace('%series_title_linked%', the_series_title($id), $replace);
340         if( stristr($replace, '%post_title_list%') )
341         $replace = str_replace('%post_title_list%', get_series_posts($id, $referral), $replace);
342         if( stristr($replace, '%post_title%') )
343         $replace = str_replace('%post_title%', series_post_title($id, FALSE), $replace);
344         if( stristr($replace, '%post_title_linked%') )
345         $replace = str_replace('%post_title_linked%', series_post_title($id), $replace);
346         if( stristr($replace, '%series_part%') )
347         $replace = str_replace('%series_part%', wp_series_part($p_id), $replace);
348         if( stristr($replace, '%series_description%') )
349         $replace = str_replace('%series_description%', series_description($id), $replace);
350         if( stristr($replace, '%next_post%') )
351         $replace = str_replace('%next_post%', wp_series_nav($id), $replace);
352         if( stristr($replace, '%previous_post%') )
353         $replace = str_replace('%previous_post%', wp_series_nav($id, FALSE), $replace);
354         if( stristr($replace, '%next_post_custom%') )
355         $replace = str_replace('%next_post_custom%', wp_series_nav($id, TRUE, TRUE), $replace);
356         if( stristr($replace, '%previous_post_custom%') )
357         $replace = str_replace('%previous_post_custom%', wp_series_nav($id, FALSE, TRUE), $replace);
358        
359         return $replace;
360         }
361
362
363 /*----------------------POST RELATED FUNCTIONS (i.e. query etc. see post.php)--------------------*/
364 //will have to add the following function for deleting the series relationship when a post is deleted.
365 function delete_series_post_relationship($postid) {
366         wp_delete_object_term_relationships($postid, 'series');
367 }
368
369 //call up series post is associated with -- needed for the post-edit panel specificaly.
370 function wp_get_post_series( $post_id = 0, $args = array() ) {
371         $post_id = (int) $post_id;
372        
373         $defaults = array('fields' => 'ids');
374         $args = wp_parse_args( $args, $defaults);
375        
376         $series = wp_get_object_terms($post_id, 'series', $args);
377        
378         return $series;
379 }
380
381 //TODO ? have to figure out how to get this added to the wp_get_single_post call (post.php - line 577)
382 function wp_get_single_post_series($postid = 0, $mode = OBJECT) {
383         global $wpdb;
384         $postid = (int) $postid;
385        
386         $post = get_post($postid, $mode);
387        
388         //set series
389         if($mode == OBJECT) {
390                 $post->series = wp_get_post_series($postid, array('fields' => 'names'));
391        
392         }
393         else {
394                 $post['series'] = wp_get_post_series($postid, array('fields' => 'names'));
395         }
396        
397         return $post;
398 }
399
400 //function to set the order that the post is in a series.
401 function set_series_order($postid = 0, $series_part = 0, $series_id) {
402        
403         if ( !isset($series_id) ) return false; // if post doesn't belong to a series yet.
404         $post_ids_in_series = get_objects_in_term($series_id, 'series');
405         $total_posts = count($post_ids_in_series);
406        
407         if (!isset($total_posts) || ($total_posts < $series_part) || $series_part ==  0 || $total_posts == 1) {
408                 if ($total_posts >=1) $series_part = $total_posts;
409         }
410                                
411         $series_posts = array();
412         $series_posts = get_series_order($post_ids_in_series, $postid);
413                
414         $ticker = 1;
415         $count = count($series_posts);
416         if ($count >= 1) {
417                 foreach ($series_posts as $sposts) {
418                         $currentpart = $sposts['part'];
419                         $spostid = $sposts['id'];
420                        
421                         if (( $ticker >= 1) && ( $series_part > 2 ) &&  ( ($series_part - $currentpart)  >= 1) && $drop )  {
422                                 $newpart = ($currentpart - 1);
423                                 $drop = TRUE;
424                         }
425                        
426                         if ( (  $ticker == 1 ) && ( $currentpart == 2 ) && ($series_part != $currentpart) && ($count >= 2 ) && !$rise ) {
427                                 $newpart = ($currentpart - 1);
428                                 $drop = TRUE;
429                         }
430                        
431                         if ( ( $ticker == 1 ) && ( $series_part == $currentpart ) && ( $series_part == 2 ) && !$rise )  {
432                                 $newpart = ($currentpart - 1);
433                                 $drop = TRUE;
434                         }
435                                
436                         if ( ($series_part == $currentpart) && ( $series_part <= $count ) && ( $series_part > 1 ) && ($series_part != 2 ) && $drop )
437                                 $newpart = ($currentpart - 1);
438                                
439                         if ( ( ($series_part == 1 ) && ($series_part >= $currentpart) ) ||  ( ( $series_part == $currentpart )  && !$drop && ($currentpart - $oldpart) < 2 ) || ( ( $series_part < $currentpart ) && ( $currentpart == $oldpart ) && !$drop ) ) {
440                                 $newpart = ($currentpart + 1);
441                                 $rise = TRUE;
442                         }
443                          
444                         if ( ($series_part == $currentpart) && ($series_part > ( $count - 2 ) ) && ($series_part != 1) && !$drop && !$rise ) {
445                                 $newpart = ($currentpart - 1);
446                                 $drop = TRUE;
447                         }
448                                
449                         if ( ($series_part == $currentpart) && ($series_part > ( $count - 2 ) ) && ($ticker == $count ) && ($series_part != 1) && !$rise ) {
450                                 $newpart = ($currentpart - 1);
451                                 $drop = TRUE;           
452                         }
453                        
454                         if (!isset($newpart))
455                                 $newpart = $currentpart;
456                                
457                         if ( isset($oldpart) && ($newpart - $oldpart) > 1 && !$drop && !$rise  && ($newpart != ($count + 1) ) ) {
458                                         $newpart = ($currentpart - 1);
459                                         $drop = TRUE;
460                                         }                       
461                        
462                         delete_post_meta($spostid, SERIES_PART_KEY);
463                         add_post_meta($spostid, SERIES_PART_KEY, $newpart);
464                         $ticker++;
465                         $oldpart = $newpart;
466                         unset($newpart);
467                        
468                 }
469         }
470         delete_post_meta($postid, SERIES_PART_KEY);
471         add_post_meta($postid, SERIES_PART_KEY, $series_part);
472         return true;
473 }
474
475 function wp_reset_series_order_meta_cache ($post_id = 0, $series_id = 0, $reset = FALSE) {
476                
477         if ( 0 == $series_id ) return false; //post is not a part of a series so no need to waste cycles.
478        
479         $post_ids_in_series = get_objects_in_term($series_id, 'series');
480        
481         $addvalue = 1;
482        
483         $series_posts = get_series_order($post_ids_in_series, $post_id);
484        
485         if ($reset) {
486                 foreach ($post_ids_in_series as $spost) {
487                         delete_post_meta($spost['object_id'], SERIES_PART_KEY);
488                 }
489                 return true;
490         }
491        
492         foreach ($series_posts as $spost) {
493                 $newpart = $addvalue;
494                 delete_post_meta($spost['id'], SERIES_PART_KEY);
495                 add_post_meta($spost['id'], SERIES_PART_KEY, $newpart);
496                 $addvalue++;
497         }
498        
499         return true;
500 }
501
502 function add_series_wp_title( $title ) {
503         global $wpdb, $wp_locale, $wp_query;
504         $series = get_query_var(SERIES_QUERYVAR);
505         $title = '';
506        
507         if ( !empty($series) ) {
508                 $series = get_term($series,'series', OBJECT, 'display');
509                 if ( is_wp_error($series) )
510                         return $series;
511                 if ( ! empty($series->name) )
512                         $title = apply_filters('single_series_title', $series->name);
513                 }
514         return $title;
515 }
516
517 add_filter('wp_title', 'add_series_wp_title');
518
519 function single_series_title($prefix = '', $display = true) {
520         $series_id = get_query_var(SERIES_QUERYVAR);
521         $serchk = is_term( $series_id, SERIES_QUERYVAR );
522        
523         if ( !empty($serchk) ) {
524                 $series_id = $serchk['term_id'];
525         }
526        
527         if ( !empty($series_id) ) {
528                 $my_series = &get_term($series_id, 'series', OBJECT, 'display');
529                 if ( is_wp_error( $my_series ) )
530                         return false;
531                 $my_series_name = apply_filters('single_tag_title', $my_series->name);
532                 if ( !empty($my_series_name) ) {
533                         if ( $display )
534                                 echo $prefix, $my_series_name;
535                         else
536                                 return $my_series_name;
537                 }
538         }
539 }
540
541 //following is modified from wp_dropdown_categories()
542 function wp_dropdown_series($args = '') {
543         $defaults = array(
544                 'show_option_all' => '', 'show_option_none' => '',
545                 'orderby' => 'ID', 'order' => 'ASC',
546                 'show_last_update' => 0, 'show_count' => 0,
547                 'hide_empty' => 1,
548                 'exclude' => '', 'echo' => 1,
549                 'selected' => 0,
550                 'name' => 'series', 'class' => 'postform'
551         );
552        
553         $defaults['selected'] = ( is_series() ) ? get_query_var('series') : 0;
554        
555         $r = wp_parse_args( $args, $defaults );
556         $r['include_last_update_time'] = $r['show_last_update'];
557         extract( $r );
558        
559         $serieslist = get_series($r);
560        
561         $output = '';
562         if ( ! empty($serieslist) ) {
563                 $output = "<select name='$name' id='$name' class='$class'>\n";
564                
565                 if ( $show_option_all ) {
566                         $show_option_all = apply_filters('list_series', $show_option_all);
567                         $output .= "\t<option value='0'>$show_option_all</option>\n";
568                 }
569                
570                 if ( $show_option_none) {
571                         $show_option_none = apply_filters('list_series', $show_option_none);
572                         $output .= "\t<option value='-1'>$show_option_none</option>\n";
573                 }
574                 foreach ($serieslist as $listseries) {         
575                         $output .= walk_series_dropdown_tree($listseries, $r);
576                 }
577                 $output .= "</select>\n";
578         }
579        
580         if ( empty( $serieslist ) ) {
581                 $output = '<select name="no-series" id="no-series" class="postform">';
582                 $output .= "\n";
583                 $output .= '<option value="-1">No Series have been started</option>';
584                 $output .= "\n";
585                 $output .= "</select>\n";
586         }
587        
588         $output = apply_filters('wp_dropdown_series', $output);
589        
590         if ( $echo )
591                 echo $output;
592                
593         return $output;
594 }
595
596 function walk_series_dropdown_tree($serieslist, $r) {
597         $series_name = apply_filters('list_series', $serieslist->name, $serieslist);
598         $output .= "\t<option value=\"" . $serieslist->term_id . "\"";
599         if ( $serieslist->term_id == $r['selected'] )
600                 $output .= ' selected="selected"';
601         $output .= '>';
602         $output .= $series_name;
603         if ( $r['show_count'] )
604                 $output .= '&nbsp;&nbsp;(' . $serieslist->count .')';
605         if ( $r['show_last_update'] ) {
606                 $format = 'Y-m-d';
607                 $output .= '&nbsp; &nbsp;' . gmdate($format, $serieslist->last_update_timestamp);
608         }
609         $output .= "</option>\n";
610        
611         return $output;
612 }
613
614 function wp_list_series($args = '') {
615         $defaults = array(
616         'show_option_all' => '', 'orderby' => 'name',
617                 'order' => 'ASC', 'show_last_update' => 0,
618                 'style' => 'list', 'show_count' => 0,
619                 'hide_empty' => 1, 'use_desc_for_title' => 1,
620                 'feed' => '', 'feed_image' => '', 'exclude' => '',
621                 'title_li' => __('Series'),
622                 'echo' => 1
623         );
624        
625         $r = wp_parse_args( $args, $defaults );
626        
627         if ( isset( $r['show_date'] ) ) {
628                 $r['include_last_update_time'] = $r['show_date'];
629         }
630        
631         extract( $r );
632        
633         $serieslist = get_series($r);
634        
635         $output = '';
636         if ( $title_li && 'list' == $style )
637                 $output = '<li class="series">' . $r['title_li'] . '<ul>';
638                
639         if ( empty($serieslist) ) {
640                 if ( 'list' == $style )
641                         $output .= '<li>' .__("No series") . '</li>';
642                 else
643                         $output .= __("No Series");
644        
645         } else {
646                 global $wp_query;
647                
648                 if (!empty($show_option_all) )
649                         if ('list' == $style )
650                                 $output .= '<li><a href="' . get_bloginfo('url') . '".' . $show_option_all . '</a></li>';
651                         else
652                                 $output .= '<a href="' . get_bloginfo('url') . '".' . $show_option_all . '</a>';
653                                
654                 if ( is_series() )
655                         $r['current_series'] = $wp_query->get_queried_object_id();
656                        
657                 foreach ( $serieslist as $listseries )
658                         $output .= walk_series_tree($listseries , $r);
659         }
660        
661         if ( $title_li && 'list' == $style )
662                 $output .= '</ul></li>';
663                
664         $output = apply_filters('wp_list_series', $output);
665        
666         if ( $echo )
667                 echo $output;
668         else
669                 return $output;
670 }
671
672 function walk_series_tree( $series, $args) {
673         if ( 'list' != $args['style'] )
674                 return $series;
675        
676         extract($args);
677        
678         $series_name = attribute_escape( $series->name );
679         $series_name = apply_filters( 'list_series' , $series_name, $series );
680         $link = '<a href="' . get_series_link( $series->term_id ) . '" ';
681         $output = '';
682         if ( $use_desc_for_title == 0 || empty($series->description) )
683                 $link .= 'title="' . sprintf(__( 'View all posts filed under %s' ), $series_name) . '"';
684         else
685                 $link .= 'title="' . attribute_escape( apply_filters( 'series_description' , $series->description, $series )) . '"';
686         $link .= '>';
687         $link .= $series_name . '</a>';
688        
689         if ( (! empty($feed_image)) || (!empty($feed)) ) {
690                 $link .= ' ';
691                
692                 if ( empty($feed_image) )
693                         $link .= '(';
694                
695                 $link .= '<a href="' . get_series_rss_link( 0, $series->term_id, $series->slug ) . '"';
696                
697                 if ( empty($feed) )
698                         $alt = ' alt="' . sprintf(__( 'Feed for all posts belonging to %s' ), $series_name ) . '"';
699                 else {
700                         $title = ' title="' . $feed . '"';
701                         $alt = ' alt="' . $feed . '"';
702                         $name = $feed;
703                         $link .= $title;
704                 }
705                
706                 $link .= '>';
707                
708                 if ( empty($feed_image) )
709                         $link .= $name;
710                 else
711                         $link .= "<img src='$feed_image'$alt$title" . ' />';
712                 $link .= '</a>';
713                 if ( empty($feed_image) )
714                         $link .= ')';
715         }
716        
717         if ( isset($show_count) && $show_count )
718                 $link .= ' (' . intval($series->count) . ')';
719                
720         if ( isset($show_date) && $show_date ) {
721                 $link .= ' ' . gmdate('Y-m-d', $series->last_update_timestamp);
722         }
723        
724         if ( 'list' == $args['style'] ) {
725                 $output .= "\t<li";
726                 $class = 'series-item series-item-'.$series->term_id;
727                 if ( $current_series && ($series->term_id == $current_series) )
728                         $class .= ' current-series';
729                 $output .= ' class="'.$class.'"';
730                 $output .= ">$link\n";
731         } else {
732                 $output .= "\t$link<br />\n";
733         }
734        
735         $output .= "</li>\n";
736         return $output;
737 }
738                
739 //wp_query stuff (see query.php) -- help for this came from examples gleaned in jeromes-keywords.php
740 function series_addQueryVar($wpvar_array) {
741         $wpvar_array[] = SERIES_QUERYVAR;
742         return($wpvar_array);
743 }
744 //for series queries
745 add_filter('query_vars', 'series_addQueryVar');
746 add_action('parse_query','series_parseQuery');
747
748
749 function series_parseQuery($query) {
750         //if this is a series query, then reset other is_x flags and add query filters
751         if (is_series()) {
752                 global $wp_query;
753                 $wp_query->is_single = false;
754                 $wp_query->is_page = false;
755                 $wp_query->is_archive = false;
756                 $wp_query->is_search = false;
757                 $wp_query->is_home = false;
758                 $wp_query->is_series = true;
759                
760                 add_filter('posts_where', 'series_postsWhere');
761                 add_filter('posts_join', 'series_postsJoin');
762                 add_action('template_redirect','series_includeTemplate');
763         }       
764 }
765
766 function is_series() {
767         global $wp_version;
768         $series = ( isset($wp_version) && ($wp_version >= 2.0) ) ? get_query_var(SERIES_QUERYVAR) : $GLOBALS[SERIES_QUERYVAR];
769         $series = get_query_var(SERIES_QUERYVAR);
770         if (!is_null($series) && ($series != ''))
771                 return true;
772         else
773                 return false;
774 }
775
776 function series_postsWhere($where) {
777         global $wpdb;
778         $series_var = get_query_var(SERIES_QUERYVAR);
779         $token = "'" . SERIES_QUERYVAR . "'";
780         //convert to series id if permalinks turned on.
781         $serchk = is_term( $series_var, SERIES_QUERYVAR );
782         if ( !empty($serchk) )
783                 $series_var = $serchk['term_id'];
784         $whichseries = '';
785        
786         if ( !empty($series_var) ) {
787                 $whichseries .= " AND $wpdb->term_taxonomy.taxonomy = $token ";
788                 $whichseries .= " AND $wpdb->term_taxonomy.term_id = $series_var ";
789         }
790                
791         $where .= "AND $wpdb->term_taxonomy.taxonomy = $token ";
792         $where .= $whichseries;
793         return ($where);
794 }
795
796 function series_postsJoin($join) {
797         global $wpdb;
798         $series_var = get_query_var(SERIES_QUERYVAR);
799         if ( !empty($series_var) )  {
800                 $join = " LEFT JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) ";
801         }
802                
803         return ($join);
804 }
805
806 function series_includeTemplate() {
807         if (is_series()) {
808                 $template = '';
809                
810                 if ( file_exists(TEMPLATEPATH. "/" . SERIES_TEMPLATE) )
811                         $template = TEMPLATEPATH . "/" . SERIES_TEMPLATE;
812                
813                 else
814                         $template = get_archive_template();
815                
816                 if ($template) {
817                         load_template($template);
818                         exit;
819                 }
820         }
821         return;
822 }
823
824 //TODO: NEED TO ADD TEMPLATE FOR SERIES TOC//
825
826 function wp_set_post_series( $post_ID = 0, $series_id = 0) {
827         $post_ID = (int) $post_ID;
828         if ( $series_id == 0 )
829                 $post_series = (int) $_POST['post_series'];
830         else
831                 $post_series = (int) $series_id;
832        
833         if ( isset($_POST) )
834                 $series_part = (int) $_POST['series_part'];
835         else
836                 $series_part = 0;
837                
838         $old_series = wp_get_post_series($post_ID);
839         $match = in_array($post_series, $old_series);
840        
841         if ( !$match ) wp_reset_series_order_meta_cache($post_ID, $old_series);
842        
843         if ( $post_series == '' ||0 == $post_series )
844                 return wp_delete_post_series_relationship($post_ID);
845        
846         $success = wp_set_object_terms($post_ID, $post_series, 'series');
847         if ( $success ) return set_series_order($post_ID, $series_part, $post_series);
848         else return FALSE;
849 }
850
851 function wp_delete_post_series_relationship( $id = 0 ) {
852         global $wpdb, $wp_rewrite;
853         $postid = (int) $id;
854         $series = get_the_series($postid);
855         $seriesid = $series->term_id;
856         delete_post_meta($postid, SERIES_PART_KEY);
857         $success = wp_delete_object_term_relationships($postid, array('series'));
858         if ( $success ) return wp_reset_series_order_meta_cache($postid, $seriesid);
859         else return FALSE;
860 }
861
862 //add_action('edit_post','wp_set_post_series');
863 //add_action('publish_post','wp_set_post_series');
864 add_action('save_post','wp_set_post_series');
865 add_action('delete_post','wp_delete_post_series_relationship');
866
867 ### taxonomy checks for series ####
868 function series_exists($series_name) {
869         $id = is_term($series_name, 'series');
870         if ( is_array($id) )
871                 $id = $id['term_id'];
872         return $id;
873 }
874
875 function get_series_to_edit ( $id ) {
876         $series = get_orgserial( $id, OBJECT, 'edit' );
877         return $series;
878 }
879
880 function wp_create_single_series($series_name) {
881         if ($id = series_exists($series_name) )
882                 return $id;
883        
884         return wp_insert_series( array('series_name' => $series_name) );
885 }
886
887 function wp_create_series($series, $post_id = '') { // this function could be used in a versions prior to 2.0 import as well.
888         $series_ids = '';
889         if ($id = series_exists($series) )
890                 $series_ids = $id;
891         elseif ($id = wp_create_single_series($series) )
892                         $series_ids = $id;
893        
894         else $id = $_POST['post_series'];
895        
896         if ($post_id)
897                 wp_set_post_series($post_id, $series_ids);
898        
899         return $series_ids;
900 }
901
902 // note following function WILL NOT delete the actual image file from the server.  I don't think it's needed at this point.
903 function wp_delete_series($series_ID) {
904         global $wpdb;
905         $series_ID = (int) $series_ID;
906                
907         seriesicons_delete($series_ID);
908         wp_reset_series_order_meta_cache('',$series_ID,TRUE);
909        
910         return wp_delete_term($series_ID, 'series');
911 }
912
913 function wp_insert_series($serarr, $file = FALSE) {
914         global $wpdb;
915        
916         extract($serarr, EXTR_SKIP);
917        
918         if ( trim( $series_name ) == '' )
919                 return 0;
920        
921         $series_ID = (int) $series_ID;
922        
923         // Are we updating or creating?
924        
925         if ( !empty ($series_ID) )
926                 $update = true;
927         else
928                 $update = false;
929                
930         $name = $series_name;
931         $description = $series_description;
932         $slug = $series_nicename;
933         $action = $action;
934         $overrides = array('action' => $action);
935         if (!($file) || $file=='') unset($file);
936        
937         if (isset($file))
938                 $iconfile = wp_handle_upload( $file, $overrides );
939        
940         //if ($message = $iconfile['error']) return FALSE; //TODO - remove the RETURN FALSE check and instead return an array for wp_insert_series containing $message, and $series_id.  This would require going back over all the files to update any calls to wp_insert_series so that returned variable is used correctly.
941         $iconname = $iconfile['url'];
942        
943         //take the $iconname which contains the full url of the series
944         $iconname = explode('/', $iconname);
945         $icon = $iconname[count($iconname) - 1];
946        
947         $args = compact('name','slug','description');
948        
949         if ( $update ) {
950                 $series_icon = seriesicons_write($series_ID, $icon);
951                 $ser_ID = wp_update_term($series_ID, 'series', $args);
952         } else {
953                 $ser_ID = wp_insert_term($series_name,'series',$args);
954                 $series_icon = seriesicons_write($ser_ID['term_id'], $icon);
955         }
956         if ( is_wp_error($ser_ID) )
957                 return 0;
958        
959         return $ser_ID['term_id'];
960 }
961
962 function wp_update_series($serarr, $file = FALSE) {
963         global $wpdb;
964        
965         $series_ID = (int) $serarr['series_ID'];
966        
967         // First, get all of the original fields
968         $series = get_orgserial($series_ID, ARRAY_A);
969        
970         // Escape stuff pulled from DB.
971         $series = add_magic_quotes($series);
972        
973         //Merge old and new fields with fields overwriting old ones.
974         $serarr = array_merge($series, $serarr);
975         return wp_insert_series($serarr, $file);
976 }
977
978 function series_rows( $series = 0 ) {
979         if ( !$series )
980                 $series = get_series( 'hide_empty=0' );
981        
982         if ( $series ) {
983                 ob_start();
984                 foreach ( $series as $serial ) {
985                         echo "\t" . _series_row( $serial );
986                 }
987                 $output = ob_get_contents();
988                 ob_end_clean();
989                
990                 $output = apply_filters('series_rows', $output);
991                
992                 echo $output;
993         } else {
994                 return false;
995         }
996 }
997
998 function _series_row($series) {
999