WordPress.org

Make WordPress Core

Ticket #6110: series-taxonomy.php.txt

File series-taxonomy.php.txt, 32.3 KB (added by nerrad, 6 years 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!
3Please 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
15function _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.
26function 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 */
56function &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       
76function &get_orgserial($orgserial, $output = OBJECT, $filter = 'raw') {
77                return get_term($orgserial, 'series', $output, $filter);
78}
79
80//permalinks , rewrite rules etc.//
81function 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
94function 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
107function 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
134function orgSeries_parse_query($wp_query) {
135        $wp_query->is_404 = false;
136}
137
138function orgSeries_request($query_vars) {
139        $query_vars['error'] = false;
140        return $query_vars;
141}
142
143function 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}
156add_action('init', 'series_init');
157
158
159/* ---------- SERIES TEMPLATE TAGS (maybe add to a series-template.php file?) --------------------------*/
160//url constructor/function template tags.
161function 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       
182function 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
203function 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
211function 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
234function 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
242function 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
254function get_series_name($series_id) {
255        $series_id = (int) $series_id;
256        $series = get_orgserial($series_id);
257        return $series->name;
258}
259
260function 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
290function 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
298function 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 **/
315function 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.
365function 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.
370function 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)
382function 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.
401function 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
475function 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
502function 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
517add_filter('wp_title', 'add_series_wp_title');
518
519function 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()
542function 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
596function 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
614function 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
672function 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
740function series_addQueryVar($wpvar_array) {
741        $wpvar_array[] = SERIES_QUERYVAR;
742        return($wpvar_array);
743}
744//for series queries
745add_filter('query_vars', 'series_addQueryVar');
746add_action('parse_query','series_parseQuery');
747
748
749function 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
766function 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
776function 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
796function 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
806function 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
826function 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
851function 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');
864add_action('save_post','wp_set_post_series');
865add_action('delete_post','wp_delete_post_series_relationship');
866
867### taxonomy checks for series ####
868function 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
875function get_series_to_edit ( $id ) {
876        $series = get_orgserial( $id, OBJECT, 'edit' );
877        return $series;
878}
879
880function 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
887function 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.
903function 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
913function 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
962function 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
978function 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
998function _series_row($series) {
999        global $class;
1000       
1001        $series_icon = series_get_icons($series->term_id);
1002        $series_url = seriesicons_url();
1003        $icon = $series_url . "/" . $series_icon;
1004       
1005        if ( current_user_can( 'manage_series' ) ) {
1006                $edit = "<a href='edit.php?page=orgSeries/orgSeries-manage.php&amp;action=edit&amp;series_ID=$series->term_id' class='edit'>".__( 'Edit' )."</a></td>";
1007                $edit .= "<td><a href='" . wp_nonce_url("edit.php?page=orgSeries/orgSeries-manage.php&amp;action=delete&amp;series_ID=$series->term_id", 'delete-series_' . $series->term_id ) . "' onclick=\"return deleteSomething('serial', $series->term_id, '" . js_escape(sprintf( __("You are about to delete the series '%s'. \nAll posts that were assigned to this series will be disassociated from the series.\n'OK' to delete, 'Cancel' to stop." ), $series->name  )) . "' );\" class='delete'>".__( 'Delete' )."</a>";
1008        } else
1009                $edit = '';
1010       
1011        $class = ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || " class='alternate'" == $class ) ? '' : " class='alternate'";
1012        $series->count = number_format_i18n( $series->count );
1013        $posts_count = ( $series->count > 0 ) ? "<a href='edit.php?series=$series->term_id'>$series->count</a>" : $series->count; 
1014        $output = "<tr id='serial-$series->term_id'$class>
1015                <th scope='row' style='text-align: center'>$series->term_id</th>
1016                <td>" . $series->name . "</td>
1017                <td>$series->description</td>
1018                <td align='center'>$posts_count</td>
1019                <td>";
1020                if (!$series_icon) {
1021                        $output .= "No icon selected";
1022                        } else {
1023                        $output .= "<img src='" . $icon . "' title='" . $series_icon . "' width='50' alt='" . $icon . "' />";
1024                        }
1025        $output .= "</td>
1026                <td>$edit</td>\n\t</tr>\n";
1027       
1028        return apply_filters('series_row', $output);
1029}
1030?>