Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 18 | class Sensei_Legacy_Shortcodes { |
||
| 19 | |||
| 20 | /** |
||
| 21 | * Add the legacy shortcodes to WordPress |
||
| 22 | * |
||
| 23 | * @since 1.9.0 |
||
| 24 | */ |
||
| 25 | public static function init(){ |
||
| 26 | |||
| 27 | add_shortcode( 'allcourses', array( __CLASS__, 'all_courses' ) ); |
||
| 28 | add_shortcode( 'newcourses', array( __CLASS__,'new_courses' ) ); |
||
| 29 | add_shortcode( 'featuredcourses', array( __CLASS__,'featured_courses') ); |
||
| 30 | add_shortcode( 'freecourses', array( __CLASS__,'free_courses') ); |
||
| 31 | add_shortcode( 'paidcourses', array( __CLASS__,'paid_courses') ); |
||
| 32 | add_shortcode( 'usercourses', array( __CLASS__,'user_courses' ) ); |
||
| 33 | |||
| 34 | } |
||
| 35 | /** |
||
| 36 | * all_courses shortcode output function. |
||
| 37 | * |
||
| 38 | * The function should only be called indirectly through do_shortcode() |
||
| 39 | * |
||
| 40 | * @access public |
||
| 41 | * @param mixed $atts |
||
| 42 | * @param mixed $content (default: null) |
||
| 43 | * @return string |
||
| 44 | */ |
||
| 45 | public static function all_courses( $atts, $content = null ) { |
||
| 46 | |||
| 47 | return self::generate_shortcode_courses( '', 'allcourses' ); // all courses but no title |
||
| 48 | |||
| 49 | } // all_courses() |
||
| 50 | |||
| 51 | /** |
||
| 52 | * paid_courses function. |
||
| 53 | * |
||
| 54 | * @access public |
||
| 55 | * @param mixed $atts |
||
| 56 | * @param mixed $content (default: null) |
||
| 57 | * @return string |
||
| 58 | */ |
||
| 59 | public static function paid_courses( $atts, $content = null ) { |
||
| 60 | |||
| 61 | return self::generate_shortcode_courses( __( 'Paid Courses', 'woothemes-sensei' ), 'paidcourses' ); |
||
| 62 | |||
| 63 | } // End paid_courses() |
||
| 64 | |||
| 65 | |||
| 66 | /** |
||
| 67 | * featured_courses function. |
||
| 68 | * |
||
| 69 | * @access public |
||
| 70 | * @param mixed $atts |
||
| 71 | * @param mixed $content (default: null) |
||
| 72 | * @return string |
||
| 73 | */ |
||
| 74 | public static function featured_courses( $atts, $content = null ) { |
||
| 75 | |||
| 76 | return self::generate_shortcode_courses( __( 'Featured Courses', 'woothemes-sensei' ), 'featuredcourses' ); |
||
| 77 | |||
| 78 | } // End featured_courses() |
||
| 79 | |||
| 80 | /** |
||
| 81 | * shortcode_free_courses function. |
||
| 82 | * |
||
| 83 | * @access public |
||
| 84 | * @param mixed $atts |
||
| 85 | * @param mixed $content (default: null) |
||
| 86 | * @return string |
||
| 87 | */ |
||
| 88 | public static function free_courses( $atts, $content = null ) { |
||
| 89 | |||
| 90 | return self::generate_shortcode_courses( __( 'Free Courses', 'woothemes-sensei' ) 'freecourses' ); |
||
|
|
|||
| 91 | |||
| 92 | } // End free_courses() |
||
| 93 | |||
| 94 | /** |
||
| 95 | * shortcode_new_courses function. |
||
| 96 | * |
||
| 97 | * @access public |
||
| 98 | * @param mixed $atts |
||
| 99 | * @param mixed $content (default: null) |
||
| 100 | * @return string |
||
| 101 | */ |
||
| 102 | public static function new_courses( $atts, $content = null ) { |
||
| 103 | |||
| 104 | return self::generate_shortcode_courses( __( 'New Courses', 'woothemes-sensei' ), 'newcourses' ); |
||
| 105 | |||
| 106 | } // End new_courses() |
||
| 107 | |||
| 108 | /** |
||
| 109 | * Generate courses adding a title. |
||
| 110 | * |
||
| 111 | * @since 1.9.0 |
||
| 112 | * |
||
| 113 | * @param $title |
||
| 114 | * @param $shortcode_specific_override |
||
| 115 | * @return string |
||
| 116 | */ |
||
| 117 | public static function generate_shortcode_courses( $title , $shortcode_specific_override ){ |
||
| 118 | |||
| 119 | global $shortcode_override, $posts_array; |
||
| 120 | |||
| 121 | $shortcode_override = $shortcode_specific_override; |
||
| 122 | |||
| 123 | // do not show this short code if there is a shortcode int he url and |
||
| 124 | // this specific shortcode is not the one requested in the ur. |
||
| 125 | $specific_shortcode_requested = isset( $_GET['action'] ) ? sanitize_text_field( $_GET['action'] ) : ''; |
||
| 126 | if( ! empty( $specific_shortcode_requested) && |
||
| 127 | $specific_shortcode_requested != $shortcode_override ){ |
||
| 128 | |||
| 129 | return ''; |
||
| 130 | |||
| 131 | } |
||
| 132 | |||
| 133 | // loop and get all courses html |
||
| 134 | ob_start(); |
||
| 135 | self::initialise_legacy_course_loop(); |
||
| 136 | $courses = ob_get_clean(); |
||
| 137 | |||
| 138 | $content = ''; |
||
| 139 | if( count( $posts_array ) > 0 ){ |
||
| 140 | |||
| 141 | $before = empty($title)? '' : '<header class="archive-header"><h2>'. $title .'</h2></header>'; |
||
| 142 | $before .= '<section id="main-course" class="course-container">'; |
||
| 143 | |||
| 144 | $after = '</section>'; |
||
| 145 | |||
| 146 | //assemble |
||
| 147 | $content = $before . $courses . $after; |
||
| 148 | |||
| 149 | } |
||
| 150 | |||
| 151 | return $content; |
||
| 152 | |||
| 153 | }// end generate_shortcode_courses |
||
| 154 | |||
| 155 | |||
| 156 | /** |
||
| 157 | * user_courses function. |
||
| 158 | * |
||
| 159 | * @access public |
||
| 160 | * @param mixed $atts |
||
| 161 | * @param mixed $content (default: null) |
||
| 162 | * @return string |
||
| 163 | */ |
||
| 164 | public static function user_courses( $atts, $content = null ) { |
||
| 165 | global $shortcode_override; |
||
| 166 | extract( shortcode_atts( array( 'amount' => 0 ), $atts ) ); |
||
| 167 | |||
| 168 | $shortcode_override = 'usercourses'; |
||
| 169 | |||
| 170 | ob_start(); |
||
| 171 | |||
| 172 | if( is_user_logged_in() ){ |
||
| 173 | |||
| 174 | Sensei_Templates::get_template( 'user/my-courses.php' ); |
||
| 175 | |||
| 176 | }else{ |
||
| 177 | |||
| 178 | Sensei()->frontend->sensei_login_form(); |
||
| 179 | |||
| 180 | } |
||
| 181 | |||
| 182 | $content = ob_get_clean(); |
||
| 183 | return $content; |
||
| 184 | |||
| 185 | } // End user_courses() |
||
| 186 | |||
| 187 | /** |
||
| 188 | * This function is simply to honor the legacy |
||
| 189 | * loop-course.php for the old shortcodes. |
||
| 190 | * @since 1.9.0 |
||
| 191 | */ |
||
| 192 | public static function initialise_legacy_course_loop(){ |
||
| 193 | |||
| 194 | global $post, $wp_query, $shortcode_override, $course_excludes; |
||
| 195 | |||
| 196 | // Handle Query Type |
||
| 197 | $query_type = ''; |
||
| 198 | |||
| 199 | if ( isset( $_GET[ 'action' ] ) && ( '' != esc_html( $_GET[ 'action' ] ) ) ) { |
||
| 200 | $query_type = esc_html( $_GET[ 'action' ] ); |
||
| 201 | } // End If Statement |
||
| 202 | |||
| 203 | if ( '' != $shortcode_override ) { |
||
| 204 | $query_type = $shortcode_override; |
||
| 205 | } // End If Statement |
||
| 206 | |||
| 207 | if ( !is_array( $course_excludes ) ) { $course_excludes = array(); } |
||
| 208 | |||
| 209 | // Check that query returns results |
||
| 210 | // Handle Pagination |
||
| 211 | $paged = $wp_query->get( 'paged' ); |
||
| 212 | $paged = empty( $paged ) ? 1 : $paged; |
||
| 213 | |||
| 214 | |||
| 215 | // Check for pagination settings |
||
| 216 | if ( isset( Sensei()->settings->settings[ 'course_archive_amount' ] ) && ( 0 < absint( Sensei()->settings->settings[ 'course_archive_amount' ] ) ) ) { |
||
| 217 | |||
| 218 | $amount = absint( Sensei()->settings->settings[ 'course_archive_amount' ] ); |
||
| 219 | |||
| 220 | } else { |
||
| 221 | |||
| 222 | $amount = $wp_query->get( 'posts_per_page' ); |
||
| 223 | |||
| 224 | } // End If Statement |
||
| 225 | |||
| 226 | // This is not a paginated page (or it's simply the first page of a paginated page/post) |
||
| 227 | |||
| 228 | global $posts_array; |
||
| 229 | $course_includes = array(); |
||
| 230 | |||
| 231 | $query_args = Sensei()->course->get_archive_query_args( $shortcode_override, $amount, $course_includes, $course_excludes ); |
||
| 232 | $course_query = new WP_Query( $query_args ); |
||
| 233 | $posts_array = $course_query->get_posts(); |
||
| 234 | |||
| 235 | // output the courses |
||
| 236 | if( ! empty( $posts_array ) ) { |
||
| 237 | |||
| 238 | //output all courses for current query |
||
| 239 | self::loop_courses( $course_query, $amount ); |
||
| 240 | |||
| 241 | } |
||
| 242 | |||
| 243 | } |
||
| 244 | |||
| 245 | /** |
||
| 246 | * Loop through courses in the query and output the infomration needed |
||
| 247 | * |
||
| 248 | * @since 1.9.0 |
||
| 249 | * |
||
| 250 | * @param WP_Query $course_query |
||
| 251 | */ |
||
| 252 | public static function loop_courses( $course_query, $amount ){ |
||
| 253 | |||
| 254 | global $shortcode_override, $posts_array, $post, $wp_query, $shortcode_override, $course_excludes, $course_includes; |
||
| 255 | |||
| 256 | if ( count( $course_query->get_posts() ) > 0 ) { |
||
| 257 | |||
| 258 | do_action( 'sensei_course_archive_header', $shortcode_override ); |
||
| 259 | |||
| 260 | foreach ( $course_query->get_posts() as $course){ |
||
| 261 | |||
| 262 | // Make sure the other loops dont include the same post twice! |
||
| 263 | array_push( $course_excludes, $course->ID ); |
||
| 264 | |||
| 265 | // output the course markup |
||
| 266 | self::the_course( $course->ID ); |
||
| 267 | |||
| 268 | } // End For Loop |
||
| 269 | |||
| 270 | // More and Prev links |
||
| 271 | $posts_array_query = new WP_Query(Sensei()->course->course_query( $shortcode_override, $amount, $course_includes, $course_excludes ) ); |
||
| 272 | $posts_array = $posts_array_query->get_posts(); |
||
| 273 | $max_pages = $course_query->found_posts / $amount; |
||
| 274 | if ( '' != $shortcode_override && ( $max_pages > $course_query->get( 'paged' ) ) ) { |
||
| 275 | |||
| 276 | switch( $shortcode_override ){ |
||
| 277 | case 'paidcourses': |
||
| 278 | $filter = 'paid'; |
||
| 279 | break; |
||
| 280 | case 'featuredcourses': |
||
| 281 | $filter = 'featured'; |
||
| 282 | break; |
||
| 283 | case 'freecourses': |
||
| 284 | $filter = 'free'; |
||
| 285 | break; |
||
| 286 | default: |
||
| 287 | $filter = ''; |
||
| 288 | break; |
||
| 289 | } |
||
| 290 | |||
| 291 | $quer_args = array(); |
||
| 292 | $quer_args[ 'paged' ] = '2'; |
||
| 293 | if( !empty( $filter ) ){ |
||
| 294 | $quer_args[ 'course_filter' ] = $filter; |
||
| 295 | } |
||
| 296 | |||
| 297 | $course_pagination_link = get_post_type_archive_link( 'course' ); |
||
| 298 | $more_link_text = esc_html( Sensei()->settings->settings[ 'course_archive_more_link_text' ] ); |
||
| 299 | $more_link_url = esc_url( add_query_arg( $quer_args, $course_pagination_link ) ); |
||
| 300 | |||
| 301 | // next/more |
||
| 302 | $html = '<div class="navigation"><div class="nav-next">'; |
||
| 303 | $html .= '<a href="' . $more_link_url . '">'; |
||
| 304 | $html .= $more_link_text; |
||
| 305 | $html .= '<span class="meta-nav"></span></a></div>'; |
||
| 306 | |||
| 307 | echo apply_filters( 'course_archive_next_link', $html ); |
||
| 308 | |||
| 309 | } // End If Statement |
||
| 310 | |||
| 311 | } // End If Statement |
||
| 312 | } |
||
| 313 | |||
| 314 | /** |
||
| 315 | * Print a single course markup |
||
| 316 | * |
||
| 317 | * @param $course_id |
||
| 318 | */ |
||
| 319 | public static function the_course( $course_id ){ |
||
| 320 | |||
| 321 | // Get meta data |
||
| 322 | $course = get_post( $course_id ); |
||
| 323 | $user_info = get_userdata( absint( $course->post_author ) ); |
||
| 324 | $author_link = get_author_posts_url( absint( $course->post_author ) ); |
||
| 325 | $author_display_name = $user_info->display_name; |
||
| 326 | $author_id = $course->post_author; |
||
| 327 | $category_output = get_the_term_list( $course_id, 'course-category', '', ', ', '' ); |
||
| 328 | $preview_lesson_count = intval( Sensei()->course->course_lesson_preview_count( $course_id ) ); |
||
| 329 | $is_user_taking_course = Sensei_Utils::user_started_course( $course_id, get_current_user_id() ); |
||
| 330 | ?> |
||
| 331 | |||
| 332 | <article class="<?php echo esc_attr( join( ' ', get_post_class( array( 'course', 'post' ), $course_id ) ) ); ?>"> |
||
| 333 | <?php |
||
| 334 | // so that legacy shortcodes work with the party plugins that wants to hook in |
||
| 335 | do_action('sensei_course_content_before',$course->ID ); |
||
| 336 | ?> |
||
| 337 | <div class="course-content"> |
||
| 338 | |||
| 339 | <?php Sensei()->course->course_image($course_id); ?> |
||
| 340 | |||
| 341 | <header> |
||
| 342 | |||
| 343 | <h2><a href="<?php echo get_permalink($course_id) ?>" title="<?php echo $course->post_title; ?>"><?php echo $course->post_title; ?></a></h2> |
||
| 344 | |||
| 345 | </header> |
||
| 346 | |||
| 347 | <section class="entry"> |
||
| 348 | |||
| 349 | <p class="sensei-course-meta"> |
||
| 350 | |||
| 351 | <?php if ( isset( Sensei()->settings->settings[ 'course_author' ] ) && ( Sensei()->settings->settings[ 'course_author' ] ) ) { ?> |
||
| 352 | <span class="course-author"><?php _e( 'by ', 'woothemes-sensei' ); ?><a href="<?php echo $author_link; ?>" title="<?php echo esc_attr( $author_display_name ); ?>"><?php echo esc_html( $author_display_name ); ?></a></span> |
||
| 353 | <?php } // End If Statement ?> |
||
| 354 | |||
| 355 | <span class="course-lesson-count"> |
||
| 356 | <?php echo Sensei()->course->course_lesson_count( $course_id ) . ' ' . __( 'Lessons', 'woothemes-sensei' ); ?> |
||
| 357 | </span> |
||
| 358 | |||
| 359 | <?php if ( '' != $category_output ) { ?> |
||
| 360 | <span class="course-category"><?php echo sprintf( __( 'in %s', 'woothemes-sensei' ), $category_output ); ?></span> |
||
| 361 | <?php } // End If Statement ?> |
||
| 362 | |||
| 363 | <?php sensei_simple_course_price( $course_id ); ?> |
||
| 364 | |||
| 365 | </p> |
||
| 366 | |||
| 367 | <p class="course-excerpt"><?php echo $course->post_excerpt; ?> |
||
| 368 | |||
| 369 | </p> |
||
| 370 | |||
| 371 | <?php if ( 0 < $preview_lesson_count && !$is_user_taking_course ) { |
||
| 372 | $preview_lessons = sprintf( __( '(%d preview lessons)', 'woothemes-sensei' ), $preview_lesson_count ); ?> |
||
| 373 | <p class="sensei-free-lessons"> |
||
| 374 | <a href="<?php echo get_permalink( $course_id ); ?>"><?php _e( 'Preview this course', 'woothemes-sensei' ) ?> |
||
| 375 | </a> - <?php echo $preview_lessons; ?> |
||
| 376 | </p> |
||
| 377 | <?php } ?> |
||
| 378 | |||
| 379 | </section> |
||
| 380 | |||
| 381 | </div> |
||
| 382 | <?php |
||
| 383 | // so that legacy shortcodes work with thir party plugins that wants to hook in |
||
| 384 | do_action('sensei_course_content_after', $course->ID); |
||
| 385 | ?> |
||
| 386 | |||
| 387 | </article> |
||
| 388 | |||
| 389 | <?php |
||
| 390 | |||
| 391 | |||
| 392 | } // end the_course |
||
| 393 | |||
| 394 | }// end class legacy shortcodes |