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 |