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:
Complex classes like Sensei_Core_Modules often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Sensei_Core_Modules, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
15 | class Sensei_Core_Modules |
||
16 | { |
||
17 | private $dir; |
||
18 | private $file; |
||
19 | private $assets_dir; |
||
20 | private $assets_url; |
||
21 | private $order_page_slug; |
||
22 | public $taxonomy; |
||
23 | |||
24 | public function __construct( $file ) |
||
25 | { |
||
26 | $this->file = $file; |
||
27 | $this->dir = dirname($this->file); |
||
28 | $this->assets_dir = trailingslashit($this->dir) . 'assets'; |
||
29 | $this->assets_url = esc_url(trailingslashit(plugins_url('/assets/', $this->file))); |
||
30 | $this->taxonomy = 'module'; |
||
31 | $this->order_page_slug = 'module-order'; |
||
32 | |||
33 | // setup taxonomy |
||
34 | add_action( 'init', array( $this, 'setup_modules_taxonomy' ), 10 ); |
||
35 | |||
36 | // Manage lesson meta boxes for taxonomy |
||
37 | add_action('add_meta_boxes', array($this, 'modules_metaboxes'), 20, 2 ); |
||
38 | |||
39 | // Save lesson meta box |
||
40 | add_action('save_post', array($this, 'save_lesson_module'), 10, 1); |
||
41 | |||
42 | //Reset the none modules lessons transient |
||
43 | add_action( 'save_post', array( 'Sensei_Core_Modules', 'reset_none_modules_transient' ) ); |
||
44 | |||
45 | // Frontend styling |
||
46 | add_action('wp_enqueue_scripts', array($this, 'enqueue_styles')); |
||
47 | |||
48 | // Admin styling |
||
49 | add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_styles')); |
||
50 | add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'), 20 , 2 ); |
||
51 | |||
52 | // Handle module completion record |
||
53 | add_action('sensei_lesson_status_updated', array($this, 'update_lesson_status_module_progress'), 10, 3); |
||
54 | add_action('sensei_user_lesson_reset', array($this, 'save_lesson_module_progress'), 10, 2); |
||
55 | add_action('wp', array($this, 'save_module_progress'), 10); |
||
56 | |||
57 | // Handle module ordering |
||
58 | add_action('admin_menu', array($this, 'register_modules_admin_menu_items'), 30 ); |
||
59 | add_filter('manage_edit-course_columns', array($this, 'course_columns'), 11, 1); |
||
60 | add_action('manage_posts_custom_column', array($this, 'course_column_content'), 11, 2); |
||
61 | |||
62 | // Ensure modules always show under courses |
||
63 | add_action( 'admin_menu', array( $this, 'remove_lessons_menu_model_taxonomy' ) , 10 ); |
||
64 | add_action( 'admin_menu', array( $this, 'remove_courses_menu_model_taxonomy' ) , 10 ); |
||
65 | add_action( 'admin_menu', array( $this, 'redirect_to_lesson_module_taxonomy_to_course' ) , 20 ); |
||
66 | |||
67 | // Add course field to taxonomy |
||
68 | add_action($this->taxonomy . '_add_form_fields', array($this, 'add_module_fields'), 50, 1); |
||
69 | add_action($this->taxonomy . '_edit_form_fields', array($this, 'edit_module_fields'), 1, 1); |
||
70 | add_action('edited_' . $this->taxonomy, array($this, 'save_module_course'), 10, 2); |
||
71 | add_action('created_' . $this->taxonomy, array($this, 'save_module_course'), 10, 2); |
||
72 | add_action('wp_ajax_sensei_json_search_courses', array($this, 'search_courses_json')); |
||
73 | |||
74 | // Manage module taxonomy archive page |
||
75 | add_filter('template_include', array($this, 'module_archive_template'), 10); |
||
76 | add_action('pre_get_posts', array($this, 'module_archive_filter'), 10, 1); |
||
77 | add_filter('sensei_lessons_archive_text', array($this, 'module_archive_title')); |
||
78 | add_action('sensei_content_lesson_inside_before', array($this, 'module_archive_description'), 11); |
||
79 | add_action('sensei_pagination', array($this, 'module_navigation_links'), 11); |
||
80 | add_filter('body_class', array($this, 'module_archive_body_class')); |
||
81 | |||
82 | // add modules to the single course template |
||
83 | add_action( 'sensei_single_course_content_inside_after', array($this, 'load_course_module_content_template') , 8 ); |
||
84 | |||
85 | //Single Course modules actions. Add to single-course/course-modules.php |
||
86 | add_action('sensei_single_course_modules_before',array( $this,'course_modules_title' ), 20); |
||
87 | |||
88 | // Set up display on single lesson page |
||
89 | add_filter('sensei_breadcrumb_output', array($this, 'module_breadcrumb_link'), 10, 2); |
||
90 | |||
91 | // Add 'Modules' columns to Analysis tables |
||
92 | add_filter('sensei_analysis_overview_columns', array($this, 'analysis_overview_column_title'), 10, 2); |
||
93 | add_filter('sensei_analysis_overview_column_data', array($this, 'analysis_overview_column_data'), 10, 3); |
||
94 | add_filter('sensei_analysis_course_columns', array($this, 'analysis_course_column_title'), 10, 2); |
||
95 | add_filter('sensei_analysis_course_column_data', array($this, 'analysis_course_column_data'), 10, 3); |
||
96 | |||
97 | // Manage module taxonomy columns |
||
98 | add_filter('manage_edit-' . $this->taxonomy . '_columns', array($this, 'taxonomy_column_headings'), 1, 1); |
||
99 | add_filter('manage_' . $this->taxonomy . '_custom_column', array($this, 'taxonomy_column_content'), 1, 3); |
||
100 | add_filter('sensei_module_lesson_list_title', array($this, 'sensei_course_preview_titles'), 10, 2); |
||
101 | |||
102 | //store new modules created on the course edit screen |
||
103 | add_action( 'wp_ajax_sensei_add_new_module_term', array( 'Sensei_Core_Modules','add_new_module_term' ) ); |
||
104 | |||
105 | // for non admin users, only show taxonomies that belong to them |
||
106 | add_filter('get_terms', array( $this, 'filter_module_terms' ), 20, 3 ); |
||
107 | add_filter('get_object_terms', array( $this, 'filter_course_selected_terms' ), 20, 3 ); |
||
108 | |||
109 | // add the teacher name next to the module term in for admin users |
||
110 | add_filter('get_terms', array( $this, 'append_teacher_name_to_module' ), 70, 3 ); |
||
111 | |||
112 | // remove the default modules metabox |
||
113 | add_action('admin_init',array( 'Sensei_Core_Modules' , 'remove_default_modules_box' )); |
||
114 | |||
115 | } // end constructor |
||
116 | |||
117 | /** |
||
118 | * Alter a module term slug when a new taxonomy term is created |
||
119 | * This will add the creators user name to the slug for uniqueness. |
||
120 | * |
||
121 | * @since 1.8.0 |
||
122 | * |
||
123 | * @param $term_id |
||
124 | * @param $tt_id |
||
125 | * @param $taxonomy |
||
126 | * |
||
127 | * @return void |
||
128 | * @deprecated since 1.9.0 |
||
129 | */ |
||
130 | public function change_module_term_slug( $term_id, $tt_id, $taxonomy ){ |
||
131 | |||
132 | _deprecated_function('change_module_term_slug', '1.9.0' ); |
||
133 | |||
134 | }// end add_module_term_group |
||
135 | |||
136 | /** |
||
137 | * Hook in all meta boxes related tot he modules taxonomy |
||
138 | * |
||
139 | * @since 1.8.0 |
||
140 | * |
||
141 | * @param string $post_type |
||
142 | * @param WP_Post $post |
||
143 | * |
||
144 | * @return void |
||
145 | */ |
||
146 | public function modules_metaboxes( $post_type, $post ) |
||
147 | { |
||
148 | if ('lesson' == $post_type ) { |
||
149 | |||
150 | // Remove default taxonomy meta box from Lesson edit screen |
||
151 | remove_meta_box($this->taxonomy . 'div', 'lesson', 'side'); |
||
152 | |||
153 | // Add custom meta box to limit module selection to one per lesson |
||
154 | add_meta_box($this->taxonomy . '_select', __('Lesson Module', 'woothemes-sensei'), array($this, 'lesson_module_metabox'), 'lesson', 'side', 'default'); |
||
155 | } |
||
156 | |||
157 | if( 'course' == $post_type ){ |
||
158 | // Course modules selection metabox |
||
159 | add_meta_box( $this->taxonomy . '_course_mb', __('Course Modules', 'woothemes-sensei'), array( $this, 'course_module_metabox'), 'course', 'side', 'core'); |
||
160 | } |
||
161 | } |
||
162 | |||
163 | /** |
||
164 | * Build content for custom module meta box |
||
165 | * |
||
166 | * @since 1.8.0 |
||
167 | * @param object $post Current post object |
||
168 | * @return void |
||
169 | */ |
||
170 | public function lesson_module_metabox($post) |
||
171 | { |
||
172 | |||
173 | // Get lesson course |
||
174 | $lesson_course = get_post_meta($post->ID, '_lesson_course', true); |
||
175 | |||
176 | $html = ''; |
||
177 | |||
178 | // Only show module selection if this lesson is part of a course |
||
179 | if ($lesson_course && $lesson_course > 0) { |
||
180 | |||
181 | // Get existing lesson module |
||
182 | $lesson_module = 0; |
||
183 | $lesson_module_list = wp_get_post_terms($post->ID, $this->taxonomy); |
||
184 | if (is_array($lesson_module_list) && count($lesson_module_list) > 0) { |
||
185 | foreach ($lesson_module_list as $single_module) { |
||
186 | $lesson_module = $single_module->term_id; |
||
187 | break; |
||
188 | } |
||
189 | } |
||
190 | |||
191 | // Get the available modules for this lesson's course |
||
192 | $modules = $this->get_course_modules($lesson_course); |
||
193 | |||
194 | // Build the HTML to output |
||
195 | $html .= '<input type="hidden" name="' . esc_attr('woo_lesson_' . $this->taxonomy . '_nonce') . '" id="' . esc_attr('woo_lesson_' . $this->taxonomy . '_nonce') . '" value="' . esc_attr(wp_create_nonce(plugin_basename($this->file))) . '" />'; |
||
196 | if (is_array($modules) && count($modules) > 0) { |
||
197 | $html .= '<select id="lesson-module-options" name="lesson_module" class="widefat">' . "\n"; |
||
198 | $html .= '<option value="">' . __('None', 'woothemes-sensei') . '</option>'; |
||
199 | foreach ($modules as $module) { |
||
200 | $html .= '<option value="' . esc_attr(absint($module->term_id)) . '"' . selected($module->term_id, $lesson_module, false) . '>' . esc_html($module->name) . '</option>' . "\n"; |
||
201 | } |
||
202 | $html .= '</select>' . "\n"; |
||
203 | } else { |
||
204 | $course_url = admin_url('post.php?post=' . urlencode($lesson_course) . '&action=edit'); |
||
205 | $html .= '<p>' . sprintf(__('No modules are available for this lesson yet. %1$sPlease add some to %3$sthe course%4$s.%2$s', 'woothemes-sensei'), '<em>', '</em>', '<a href="' . esc_url($course_url) . '">', '</a>') . '</p>'; |
||
206 | } // End If Statement |
||
207 | |||
208 | } else { |
||
209 | $html .= '<p>' . sprintf(__('No modules are available for this lesson yet. %1$sPlease select a course first.%2$s', 'woothemes-sensei'), '<em>', '</em>') . '</p>'; |
||
210 | } // End If Statement |
||
211 | |||
212 | // Output the HTML |
||
213 | echo $html; |
||
214 | } |
||
215 | |||
216 | /** |
||
217 | * Save module to lesson |
||
218 | * |
||
219 | * @since 1.8.0 |
||
220 | * @param integer $post_id ID of post |
||
221 | * @return mixed Post ID on permissions failure, boolean true on success |
||
222 | */ |
||
223 | public function save_lesson_module($post_id) |
||
224 | { |
||
225 | global $post; |
||
226 | |||
227 | // Verify post type and nonce |
||
228 | View Code Duplication | if ((get_post_type() != 'lesson') || !isset($_POST['woo_lesson_' . $this->taxonomy . '_nonce'] ) |
|
229 | ||!wp_verify_nonce($_POST['woo_lesson_' . $this->taxonomy . '_nonce'], plugin_basename($this->file))) { |
||
230 | return $post_id; |
||
231 | } |
||
232 | |||
233 | // Check if user has permissions to edit lessons |
||
234 | $post_type = get_post_type_object($post->post_type); |
||
235 | if (!current_user_can($post_type->cap->edit_post, $post_id)) { |
||
236 | return $post_id; |
||
237 | } |
||
238 | |||
239 | // Check if user has permissions to edit this specific post |
||
240 | if (!current_user_can('edit_post', $post_id)) { |
||
241 | return $post_id; |
||
242 | } |
||
243 | |||
244 | // Cast module ID as an integer if selected, otherwise leave as empty string |
||
245 | if ( isset( $_POST['lesson_module'] ) ) { |
||
246 | |||
247 | if( empty ( $_POST['lesson_module'] ) ){ |
||
248 | wp_delete_object_term_relationships($post_id, $this->taxonomy ); |
||
249 | return true; |
||
250 | } |
||
251 | |||
252 | $module_id = intval( $_POST['lesson_module'] ); |
||
253 | |||
254 | // Assign lesson to selected module |
||
255 | wp_set_object_terms($post_id, $module_id, $this->taxonomy, false); |
||
256 | |||
257 | // Set default order for lesson inside module |
||
258 | if (!get_post_meta($post_id, '_order_module_' . $module_id, true)) { |
||
259 | update_post_meta($post_id, '_order_module_' . $module_id, 0); |
||
260 | } |
||
261 | } |
||
262 | |||
263 | return true; |
||
264 | } |
||
265 | |||
266 | /** |
||
267 | * Display course field on new module screen |
||
268 | * |
||
269 | * @since 1.8.0 |
||
270 | * @param object $taxonomy Taxonomy object |
||
271 | * @return void |
||
272 | */ |
||
273 | public function add_module_fields($taxonomy) |
||
274 | { |
||
275 | ?> |
||
276 | <div class="form-field"> |
||
277 | <label for="module_courses"><?php _e('Course(s)', 'woothemes-sensei'); ?></label> |
||
278 | <input type="hidden" id="module_courses" name="module_courses" class="ajax_chosen_select_courses" |
||
279 | placeholder="<?php esc_attr_e('Search for courses', 'woothemes-sensei'); ?>" /> |
||
280 | <span |
||
281 | class="description"><?php _e('Search for and select the courses that this module will belong to.', 'woothemes-sensei'); ?></span> |
||
282 | </div> |
||
283 | <?php |
||
284 | } |
||
285 | |||
286 | /** |
||
287 | * Display course field on module edit screen |
||
288 | * |
||
289 | * @since 1.8.0 |
||
290 | * @param object $module Module term object |
||
291 | * @return void |
||
292 | */ |
||
293 | public function edit_module_fields($module) |
||
294 | { |
||
295 | |||
296 | $module_id = $module->term_id; |
||
297 | |||
298 | // Get module's existing courses |
||
299 | $args = array( |
||
300 | 'post_type' => 'course', |
||
301 | 'post_status' => array('publish', 'draft', 'future', 'private'), |
||
302 | 'posts_per_page' => -1, |
||
303 | 'tax_query' => array( |
||
304 | array( |
||
305 | 'taxonomy' => $this->taxonomy, |
||
306 | 'field' => 'id', |
||
307 | 'terms' => $module_id |
||
308 | ) |
||
309 | ) |
||
310 | ); |
||
311 | $courses = get_posts($args); |
||
312 | |||
313 | //build the defaults array |
||
314 | $module_courses = array(); |
||
315 | if (isset($courses) && is_array($courses)) { |
||
316 | foreach ($courses as $course) { |
||
317 | $module_courses[] = array( 'id' =>$course->ID, 'details'=>$course->post_title ); |
||
318 | } |
||
319 | } |
||
320 | |||
321 | ?> |
||
322 | <tr class="form-field"> |
||
323 | <th scope="row" valign="top"><label |
||
324 | for="module_courses"><?php _e('Course(s)', 'woothemes-sensei'); ?></label></th> |
||
325 | <td> |
||
326 | <input type="hidden" |
||
327 | data-defaults="<?php echo esc_attr( json_encode($module_courses)); ?>" |
||
328 | value="<?php echo esc_attr( json_encode($module_courses) ); ?>" |
||
329 | id="module_courses" name="module_courses" |
||
330 | class="ajax_chosen_select_courses" |
||
331 | placeholder="<?php esc_attr_e('Search for courses...', 'woothemes-sensei'); ?>" |
||
332 | /> |
||
333 | <span |
||
334 | class="description"><?php _e('Search for and select the courses that this module will belong to.', 'woothemes-sensei'); ?></span> |
||
335 | </td> |
||
336 | </tr> |
||
337 | <?php |
||
338 | } |
||
339 | |||
340 | /** |
||
341 | * Save module course on add/edit |
||
342 | * |
||
343 | * @since 1.8.0 |
||
344 | * @param integer $module_id ID of module |
||
345 | * @return void |
||
346 | */ |
||
347 | public function save_module_course($module_id) |
||
348 | { |
||
349 | |||
350 | // Get module's existing courses |
||
351 | $args = array( |
||
352 | 'post_type' => 'course', |
||
353 | 'post_status' => array('publish', 'draft', 'future', 'private'), |
||
354 | 'posts_per_page' => -1, |
||
355 | 'tax_query' => array( |
||
356 | array( |
||
357 | 'taxonomy' => $this->taxonomy, |
||
358 | 'field' => 'id', |
||
359 | 'terms' => $module_id |
||
360 | ) |
||
361 | ) |
||
362 | ); |
||
363 | $courses = get_posts($args); |
||
364 | |||
365 | // Remove module from existing courses |
||
366 | if (isset($courses) && is_array($courses)) { |
||
367 | foreach ($courses as $course) { |
||
368 | wp_remove_object_terms($course->ID, $module_id, $this->taxonomy); |
||
369 | } |
||
370 | } |
||
371 | |||
372 | // Add module to selected courses |
||
373 | if ( isset( $_POST['module_courses'] ) && ! empty( $_POST['module_courses'] ) ) { |
||
374 | |||
375 | $course_ids = explode( ",", $_POST['module_courses'] ); |
||
376 | |||
377 | foreach ( $course_ids as $course_id ) { |
||
378 | |||
379 | wp_set_object_terms($course_id, $module_id, $this->taxonomy, true); |
||
380 | |||
381 | } |
||
382 | } |
||
383 | } |
||
384 | |||
385 | /** |
||
386 | * Ajax function to search for courses matching term |
||
387 | * |
||
388 | * @since 1.8.0 |
||
389 | * @return void |
||
390 | */ |
||
391 | public function search_courses_json() |
||
392 | { |
||
393 | |||
394 | // Security check |
||
395 | check_ajax_referer('search-courses', 'security'); |
||
396 | |||
397 | // Set content type |
||
398 | header('Content-Type: application/json; charset=utf-8'); |
||
399 | |||
400 | // Get user input |
||
401 | $term = urldecode(stripslashes($_GET['term'])); |
||
402 | |||
403 | // Return nothing if term is empty |
||
404 | if (empty($term)) |
||
405 | die(); |
||
406 | |||
407 | // Set a default if none is given |
||
408 | $default = isset($_GET['default']) ? $_GET['default'] : __('No course', 'woothemes-sensei'); |
||
409 | |||
410 | // Set up array of results |
||
411 | $found_courses = array('' => $default); |
||
412 | |||
413 | // Fetch results |
||
414 | $args = array( |
||
415 | 'post_type' => 'course', |
||
416 | 'post_status' => array('publish', 'draft', 'future', 'private'), |
||
417 | 'posts_per_page' => -1, |
||
418 | 'orderby' => 'title', |
||
419 | 's' => $term |
||
420 | ); |
||
421 | $courses = get_posts($args); |
||
422 | |||
423 | // Add results to array |
||
424 | if ($courses) { |
||
425 | foreach ($courses as $course) { |
||
426 | $found_courses[$course->ID] = $course->post_title; |
||
427 | } |
||
428 | } |
||
429 | |||
430 | // Encode and return results for processing & selection |
||
431 | echo json_encode($found_courses); |
||
432 | die(); |
||
433 | } |
||
434 | |||
435 | /** |
||
436 | * display modules on single course pages |
||
437 | * |
||
438 | * @since 1.8.0 |
||
439 | * @return void |
||
440 | */ |
||
441 | public function single_course_modules(){ |
||
442 | |||
443 | _deprecated_function('Sensei_Modules->single_course_modules','Sensei 1.9.0', 'Sensei()->modules->load_course_module_content_template'); |
||
444 | // only show modules on the course that has modules |
||
445 | if( is_singular( 'course' ) && has_term( '', 'module' ) ) { |
||
446 | |||
447 | $this->load_course_module_content_template(); |
||
448 | |||
449 | } |
||
450 | |||
451 | } // end single_course_modules |
||
452 | |||
453 | public function sensei_course_preview_titles($title, $lesson_id) |
||
454 | { |
||
455 | global $post, $current_user; |
||
456 | |||
457 | $course_id = $post->ID; |
||
458 | $title_text = ''; |
||
459 | |||
460 | if (method_exists('Sensei_Utils', 'is_preview_lesson') && Sensei_Utils::is_preview_lesson($lesson_id)) { |
||
461 | $is_user_taking_course = Sensei_Utils::sensei_check_for_activity(array('post_id' => $course_id, 'user_id' => $current_user->ID, 'type' => 'sensei_course_status')); |
||
462 | if (!$is_user_taking_course) { |
||
463 | if (method_exists('WooThemes_Sensei_Frontend', 'sensei_lesson_preview_title_text')) { |
||
464 | $title_text = Sensei()->frontend->sensei_lesson_preview_title_text($course_id); |
||
465 | // Remove brackets for display here |
||
466 | $title_text = str_replace('(', '', $title_text); |
||
467 | $title_text = str_replace(')', '', $title_text); |
||
468 | $title_text = '<span class="preview-label">' . $title_text . '</span>'; |
||
469 | } |
||
470 | $title .= ' ' . $title_text; |
||
471 | } |
||
472 | } |
||
473 | |||
474 | return $title; |
||
475 | } |
||
476 | |||
477 | public function module_breadcrumb_link($html, $separator) |
||
478 | { |
||
479 | global $post; |
||
480 | // Lesson |
||
481 | if (is_singular('lesson')) { |
||
482 | if (has_term('', $this->taxonomy, $post->ID)) { |
||
483 | $module = $this->get_lesson_module($post->ID); |
||
484 | if( $module ) { |
||
485 | $html .= ' ' . $separator . ' <a href="' . esc_url($module->url) . '" title="' . __('Back to the module', 'woothemes-sensei') . '">' . $module->name . '</a>'; |
||
486 | } |
||
487 | } |
||
488 | } |
||
489 | // Module |
||
490 | if (is_tax($this->taxonomy)) { |
||
491 | if (isset($_GET['course_id']) && 0 < intval($_GET['course_id'])) { |
||
492 | $course_id = intval($_GET['course_id']); |
||
493 | $html .= '<a href="' . esc_url(get_permalink($course_id)) . '" title="' . __('Back to the course', 'woothemes-sensei') . '">' . get_the_title($course_id) . '</a>'; |
||
494 | } |
||
495 | } |
||
496 | return $html; |
||
497 | } |
||
498 | |||
499 | /** |
||
500 | * Set lesson archive template to display on module taxonomy archive page |
||
501 | * |
||
502 | * @since 1.8.0 |
||
503 | * @param string $template Default template |
||
504 | * @return string Modified template |
||
505 | */ |
||
506 | public function module_archive_template($template) { |
||
507 | |||
508 | if ( ! is_tax($this->taxonomy) ) { |
||
509 | return $template; |
||
510 | } |
||
511 | |||
512 | $file = 'archive-lesson.php'; |
||
513 | $find = array( $file, Sensei()->template_url . $file ); |
||
514 | |||
515 | // locate the template file |
||
516 | $template = locate_template($find); |
||
517 | if (!$template) { |
||
518 | |||
519 | $template = Sensei()->plugin_path() . 'templates/' . $file; |
||
520 | |||
521 | } |
||
522 | |||
523 | |||
524 | return $template; |
||
525 | } |
||
526 | |||
527 | /** |
||
528 | * Modify module taxonomy archive query |
||
529 | * |
||
530 | * @since 1.8.0 |
||
531 | * @param object $query The query object passed by reference |
||
532 | * @return void |
||
533 | */ |
||
534 | public function module_archive_filter($query) |
||
535 | { |
||
536 | if (is_tax($this->taxonomy) && $query->is_main_query()) { |
||
537 | |||
538 | |||
539 | // Limit to lessons only |
||
540 | $query->set('post_type', 'lesson'); |
||
541 | |||
542 | // Set order of lessons |
||
543 | if (version_compare(Sensei()->version, '1.6.0', '>=')) { |
||
544 | $module_id = $query->queried_object_id; |
||
545 | $query->set('meta_key', '_order_module_' . $module_id); |
||
546 | $query->set('orderby', 'meta_value_num date'); |
||
547 | } else { |
||
548 | $query->set('orderby', 'menu_order'); |
||
549 | } |
||
550 | $query->set('order', 'ASC'); |
||
551 | |||
552 | // Limit to specific course if specified |
||
553 | if (isset($_GET['course_id']) && 0 < intval($_GET['course_id'])) { |
||
554 | $course_id = intval($_GET['course_id']); |
||
555 | $meta_query[] = array( |
||
556 | 'key' => '_lesson_course', |
||
557 | 'value' => intval($course_id) |
||
558 | ); |
||
559 | $query->set('meta_query', $meta_query); |
||
560 | } |
||
561 | |||
562 | } |
||
563 | } |
||
564 | |||
565 | /** |
||
566 | * Modify archive page title |
||
567 | * |
||
568 | * @since 1.8.0 |
||
569 | * @param string $title Default title |
||
570 | * @return string Modified title |
||
571 | */ |
||
572 | public function module_archive_title($title) |
||
573 | { |
||
574 | if (is_tax($this->taxonomy)) { |
||
575 | $title = apply_filters('sensei_module_archive_title', get_queried_object()->name); |
||
576 | } |
||
577 | return $title; |
||
578 | } |
||
579 | |||
580 | /** |
||
581 | * Display module description on taxonomy archive page |
||
582 | * |
||
583 | * @since 1.8.0 |
||
584 | * @return void |
||
585 | */ |
||
586 | public function module_archive_description() |
||
587 | { |
||
588 | if (is_tax($this->taxonomy)) { |
||
589 | |||
590 | $module = get_queried_object(); |
||
591 | |||
592 | $module_progress = false; |
||
593 | if (is_user_logged_in() && isset($_GET['course_id']) && intval($_GET['course_id']) > 0) { |
||
594 | global $current_user; |
||
595 | wp_get_current_user(); |
||
596 | $module_progress = $this->get_user_module_progress($module->term_id, $_GET['course_id'], $current_user->ID); |
||
597 | } |
||
598 | |||
599 | if ($module_progress && $module_progress > 0) { |
||
600 | $status = __('Completed', 'woothemes-sensei'); |
||
601 | $class = 'completed'; |
||
602 | if ($module_progress < 100) { |
||
603 | $status = __('In progress', 'woothemes-sensei'); |
||
604 | $class = 'in-progress'; |
||
605 | } |
||
606 | echo '<p class="status ' . esc_attr($class) . '">' . $status . '</p>'; |
||
607 | } |
||
608 | |||
609 | echo '<p class="archive-description module-description">' . apply_filters('sensei_module_archive_description', nl2br($module->description), $module->term_id) . '</p>'; |
||
610 | } |
||
611 | } |
||
612 | |||
613 | public function module_archive_body_class($classes) |
||
614 | { |
||
615 | if (is_tax($this->taxonomy)) { |
||
616 | $classes[] = 'module-archive'; |
||
617 | } |
||
618 | return $classes; |
||
619 | } |
||
620 | |||
621 | /** |
||
622 | * Display module navigation links on module taxonomy archive page |
||
623 | * |
||
624 | * @since 1.8.0 |
||
625 | * @return void |
||
626 | */ |
||
627 | public function module_navigation_links() |
||
628 | { |
||
629 | if (is_tax($this->taxonomy) && isset($_GET['course_id'])) { |
||
630 | |||
631 | $queried_module = get_queried_object(); |
||
632 | $course_modules = $this->get_course_modules($_GET['course_id']); |
||
633 | |||
634 | $prev_module = false; |
||
635 | $next_module = false; |
||
636 | $on_current = false; |
||
637 | foreach ($course_modules as $module) { |
||
638 | $this_module = $module; |
||
639 | if ($on_current) { |
||
640 | $next_module = $this_module; |
||
641 | break; |
||
642 | } |
||
643 | if ($this_module == $queried_module) { |
||
644 | $on_current = true; |
||
645 | } else { |
||
646 | $prev_module = $module; |
||
647 | } |
||
648 | } |
||
649 | |||
650 | ?> |
||
651 | <div id="post-entries" class="post-entries module-navigation fix"> |
||
652 | View Code Duplication | <?php if ($next_module) { |
|
653 | $module_link = add_query_arg('course_id', intval($_GET['course_id']), get_term_link($next_module, $this->taxonomy)); |
||
654 | ?> |
||
655 | <div class="nav-next fr"><a href="<?php echo esc_url($module_link); ?>" |
||
656 | title="<?php esc_attr_e('Next module', 'woothemes-sensei'); ?>"><?php echo $next_module->name; ?> |
||
657 | <span class="meta-nav"></span></a></div> |
||
658 | <?php } ?> |
||
659 | View Code Duplication | <?php if ($prev_module) { |
|
660 | $module_link = add_query_arg('course_id', intval($_GET['course_id']), get_term_link($prev_module, $this->taxonomy)); |
||
661 | ?> |
||
662 | <div class="nav-prev fl"><a href="<?php echo esc_url($module_link); ?>" |
||
663 | title="<?php _e('Previous module', 'woothemes-sensei'); ?>"><span |
||
664 | class="meta-nav"></span> <?php echo $prev_module->name; ?></a></div> |
||
665 | <?php } ?> |
||
666 | </div> |
||
667 | <?php |
||
668 | } |
||
669 | } |
||
670 | |||
671 | /** |
||
672 | * Trigger save_lesson_module_progress() when a lesson status is updated for a specific user |
||
673 | * |
||
674 | * @since 1.8.0 |
||
675 | * @param string $status Status of the lesson for the user |
||
676 | * @param integer $user_id ID of user |
||
677 | * @param integer $lesson_id ID of lesson |
||
678 | * @return void |
||
679 | */ |
||
680 | public function update_lesson_status_module_progress($status = '', $user_id = 0, $lesson_id = 0) |
||
684 | |||
685 | /** |
||
686 | * Save lesson's module progress for a specific user |
||
687 | * |
||
688 | * @since 1.8.0 |
||
689 | * @param integer $user_id ID of user |
||
690 | * @param integer $lesson_id ID of lesson |
||
691 | * @return void |
||
692 | */ |
||
693 | public function save_lesson_module_progress($user_id = 0, $lesson_id = 0) |
||
694 | { |
||
695 | $module = $this->get_lesson_module($lesson_id); |
||
696 | $course_id = get_post_meta($lesson_id, '_lesson_course', true); |
||
697 | if ($module && $course_id) { |
||
698 | $this->save_user_module_progress(intval($module->term_id), intval($course_id), intval($user_id)); |
||
699 | } |
||
700 | } |
||
701 | |||
702 | /** |
||
703 | * Save progress of module for user |
||
704 | * |
||
705 | * @since 1.8.0 |
||
706 | * @return void |
||
707 | */ |
||
708 | public function save_module_progress() |
||
720 | |||
721 | /** |
||
722 | * Save module progess for user |
||
723 | * |
||
724 | * @since 1.8.0 |
||
725 | * |
||
726 | * @param integer $module_id ID of module |
||
727 | * @param integer $course_id ID of course |
||
728 | * @param integer $user_id ID of user |
||
729 | * @return void |
||
730 | */ |
||
731 | public function save_user_module_progress($module_id = 0, $course_id = 0, $user_id = 0) |
||
738 | |||
739 | /** |
||
740 | * Get module progress for a user |
||
741 | * |
||
742 | * @since 1.8.0 |
||
743 | * |
||
744 | * @param integer $module_id ID of module |
||
745 | * @param integer $course_id ID of course |
||
746 | * @param integer $user_id ID of user |
||
747 | * @return mixed Module progress percentage on success, false on failure |
||
748 | */ |
||
749 | public function get_user_module_progress($module_id = 0, $course_id = 0, $user_id = 0) |
||
757 | |||
758 | /** |
||
759 | * Calculate module progess for user |
||
760 | * |
||
761 | * @since 1.8.0 |
||
762 | * |
||
763 | * @param integer $user_id ID of user |
||
764 | * @param integer $module_id ID of module |
||
765 | * @param integer $course_id ID of course |
||
766 | * @return integer Module progress percentage |
||
767 | */ |
||
768 | public function calculate_user_module_progress($user_id = 0, $module_id = 0, $course_id = 0) |
||
808 | |||
809 | /** |
||
810 | * Register admin screen for ordering modules |
||
811 | * |
||
812 | * @since 1.8.0 |
||
813 | * |
||
814 | * @return void |
||
815 | */ |
||
816 | public function register_modules_admin_menu_items() |
||
825 | |||
826 | /** |
||
827 | * Display Module Order screen |
||
828 | * |
||
829 | * @since 1.8.0 |
||
830 | * |
||
831 | * @return void |
||
832 | */ |
||
833 | public function module_order_screen() |
||
919 | |||
920 | /** |
||
921 | * Add 'Module order' column to courses list table |
||
922 | * |
||
923 | * @since 1.8.0 |
||
924 | * |
||
925 | * @param array $columns Existing columns |
||
926 | * @return array Modifed columns |
||
927 | */ |
||
928 | public function course_columns($columns = array()) |
||
933 | |||
934 | /** |
||
935 | * Load content in 'Module order' column |
||
936 | * |
||
937 | * @since 1.8.0 |
||
938 | * |
||
939 | * @param string $column Current column name |
||
940 | * @param integer $course_id ID of course |
||
941 | * @return void |
||
942 | */ |
||
943 | public function course_column_content($column = '', $course_id = 0) |
||
951 | |||
952 | /** |
||
953 | * Save module order for course |
||
954 | * |
||
955 | * @since 1.8.0 |
||
956 | * |
||
957 | * @param string $order_string Comma-separated string of module IDs |
||
958 | * @param integer $course_id ID of course |
||
959 | * @return boolean True on success, false on failure |
||
960 | */ |
||
961 | private function save_course_module_order($order_string = '', $course_id = 0) |
||
970 | |||
971 | /** |
||
972 | * Get module order for course |
||
973 | * |
||
974 | * @since 1.8.0 |
||
975 | * |
||
976 | * @param integer $course_id ID of course |
||
977 | * @return mixed Module order on success, false if no module order has been saved |
||
978 | */ |
||
979 | public function get_course_module_order($course_id = 0) |
||
987 | |||
988 | /** |
||
989 | * Modify module taxonomy columns |
||
990 | * |
||
991 | * @since 1.8.0 |
||
992 | * |
||
993 | * @param array $columns Default columns |
||
994 | * @return array Modified columns |
||
995 | */ |
||
996 | public function taxonomy_column_headings($columns) |
||
1005 | |||
1006 | /** |
||
1007 | * Manage content in custom module taxonomy columns |
||
1008 | * |
||
1009 | * @since 1.8.0 |
||
1010 | * |
||
1011 | * @param string $column_data Default data for column |
||
1012 | * @param string $column_name Name of current column |
||
1013 | * @param integer $term_id ID of current term |
||
1014 | * @return string Modified column data |
||
1015 | */ |
||
1016 | public function taxonomy_column_content($column_data, $column_name, $term_id) |
||
1045 | |||
1046 | /** |
||
1047 | * Add 'Module' columns to Analysis Lesson Overview table |
||
1048 | * |
||
1049 | * @since 1.8.0 |
||
1050 | * |
||
1051 | * @param array $columns Default columns |
||
1052 | * @return array Modified columns |
||
1053 | */ |
||
1054 | public function analysis_overview_column_title($columns) |
||
1075 | |||
1076 | /** |
||
1077 | * Data for 'Module' column Analysis Lesson Overview table |
||
1078 | * |
||
1079 | * @since 1.8.0 |
||
1080 | * |
||
1081 | * @param array $columns Table column data |
||
1082 | * @param WP_Post $lesson |
||
1083 | * @return array Updated column data |
||
1084 | */ |
||
1085 | View Code Duplication | public function analysis_overview_column_data($columns, $lesson ) |
|
1103 | |||
1104 | /** |
||
1105 | * Add 'Module' columns to Analysis Course table |
||
1106 | * |
||
1107 | * @since 1.8.0 |
||
1108 | * |
||
1109 | * @param array $columns Default columns |
||
1110 | * @return array Modified columns |
||
1111 | */ |
||
1112 | public function analysis_course_column_title($columns) |
||
1119 | |||
1120 | /** |
||
1121 | * Data for 'Module' column in Analysis Course table |
||
1122 | * |
||
1123 | * @since 1.8.0 |
||
1124 | * |
||
1125 | * @param array $columns Table column data |
||
1126 | * @param WP_Post $lesson |
||
1127 | * @return array Updated columns data |
||
1128 | */ |
||
1129 | View Code Duplication | public function analysis_course_column_data($columns, $lesson ) |
|
1147 | |||
1148 | /** |
||
1149 | * Get module for lesson |
||
1150 | * |
||
1151 | * This function also checks if the module still |
||
1152 | * exists on the course before returning it. Although |
||
1153 | * the lesson has a module the same module must exist on the |
||
1154 | * course for it to be valid. |
||
1155 | * |
||
1156 | * @since 1.8.0 |
||
1157 | * |
||
1158 | * @param integer $lesson_id ID of lesson |
||
1159 | * @return object Module taxonomy term object |
||
1160 | */ |
||
1161 | public function get_lesson_module($lesson_id = 0) |
||
1204 | |||
1205 | /** |
||
1206 | * Get ordered array of all modules in course |
||
1207 | * |
||
1208 | * @since 1.8.0 |
||
1209 | * |
||
1210 | * @param integer $course_id ID of course |
||
1211 | * @return array Ordered array of module taxonomy term objects |
||
1212 | */ |
||
1213 | public function get_course_modules($course_id = 0) { |
||
1214 | |||
1215 | $course_id = intval($course_id); |
||
1216 | if ( empty( $course_id ) ) { |
||
1217 | return array(); |
||
1218 | } |
||
1219 | |||
1220 | // Get modules for course |
||
1221 | $modules = wp_get_post_terms( $course_id, $this->taxonomy ); |
||
1222 | |||
1223 | // Get custom module order for course |
||
1224 | $order = $this->get_course_module_order($course_id); |
||
1225 | |||
1226 | if ( ! $order) { |
||
1227 | return $modules; |
||
1228 | } |
||
1229 | |||
1230 | // Sort by custom order |
||
1231 | $ordered_modules = array(); |
||
1232 | $unordered_modules = array(); |
||
1233 | foreach ( $modules as $module ) { |
||
1234 | $order_key = array_search($module->term_id, $order); |
||
1235 | if ($order_key !== false) { |
||
1236 | $ordered_modules[$order_key] = $module; |
||
1237 | } else { |
||
1238 | $unordered_modules[] = $module; |
||
1239 | } |
||
1240 | } |
||
1241 | |||
1242 | // Order modules correctly |
||
1243 | ksort( $ordered_modules ); |
||
1244 | |||
1245 | // Append modules that have not yet been ordered |
||
1246 | if ( count($unordered_modules) > 0 ) { |
||
1247 | $ordered_modules = array_merge($ordered_modules, $unordered_modules); |
||
1248 | } |
||
1249 | |||
1250 | // remove order key but maintain order |
||
1251 | $ordered_modules_with_keys_in_sequence = array(); |
||
1252 | foreach ( $ordered_modules as $key => $module ) { |
||
1253 | |||
1254 | $ordered_modules_with_keys_in_sequence[] = $module; |
||
1255 | |||
1256 | } |
||
1257 | |||
1258 | return $ordered_modules_with_keys_in_sequence; |
||
1259 | |||
1260 | } |
||
1261 | |||
1262 | /** |
||
1263 | * Load frontend CSS |
||
1264 | * |
||
1265 | * @since 1.8.0 |
||
1266 | * |
||
1267 | * @return void |
||
1268 | */ |
||
1269 | public function enqueue_styles() { |
||
1275 | |||
1276 | /** |
||
1277 | * Load admin Javascript |
||
1278 | * |
||
1279 | * @since 1.8.0 |
||
1280 | * |
||
1281 | * @return void |
||
1282 | */ |
||
1283 | public function admin_enqueue_scripts( $hook ) { |
||
1315 | |||
1316 | /** |
||
1317 | * Load admin CSS |
||
1318 | * |
||
1319 | * @since 1.8.0 |
||
1320 | * |
||
1321 | * @return void |
||
1322 | */ |
||
1323 | public function admin_enqueue_styles() { |
||
1329 | |||
1330 | /** |
||
1331 | * Show the title modules on the single course template. |
||
1332 | * |
||
1333 | * Function is hooked into sensei_single_course_modules_before. |
||
1334 | * |
||
1335 | * @since 1.8.0 |
||
1336 | * @return void |
||
1337 | */ |
||
1338 | public function course_modules_title( ) { |
||
1347 | |||
1348 | /** |
||
1349 | * Display the single course modules content this will only show |
||
1350 | * if the course has modules. |
||
1351 | * |
||
1352 | * @since 1.8.0 |
||
1353 | * @return void |
||
1354 | */ |
||
1355 | View Code Duplication | public function load_course_module_content_template(){ |
|
1373 | |||
1374 | /** |
||
1375 | * Returns all lessons for the given module ID |
||
1376 | * |
||
1377 | * @since 1.8.0 |
||
1378 | * |
||
1379 | * @param $course_id |
||
1380 | * @param $term_id |
||
1381 | * @return array $lessons |
||
1382 | */ |
||
1383 | public function get_lessons( $course_id , $term_id ){ |
||
1398 | |||
1399 | /** |
||
1400 | * Returns all lessons for the given module ID |
||
1401 | * |
||
1402 | * @since 1.8.0 |
||
1403 | * |
||
1404 | * @param $course_id |
||
1405 | * @param $term_id |
||
1406 | * @return WP_Query $lessons_query |
||
1407 | */ |
||
1408 | public function get_lessons_query( $course_id , $term_id ){ |
||
1449 | |||
1450 | /** |
||
1451 | * Find the lesson in the given course that doesn't belong |
||
1452 | * to any of the courses modules |
||
1453 | * |
||
1454 | * |
||
1455 | * @param $course_id |
||
1456 | * |
||
1457 | * @return array $non_module_lessons |
||
1458 | */ |
||
1459 | public function get_none_module_lessons( $course_id ){ |
||
1526 | |||
1527 | /** |
||
1528 | * Register the modules taxonomy |
||
1529 | * |
||
1530 | * @since 1.8.0 |
||
1531 | */ |
||
1532 | public function setup_modules_taxonomy(){ |
||
1576 | |||
1577 | /** |
||
1578 | * When the wants to edit the lesson modules redirect them to the course modules. |
||
1579 | * |
||
1580 | * This function is hooked into the admin_menu |
||
1581 | * |
||
1582 | * @since 1.8.0 |
||
1583 | * @return void |
||
1584 | */ |
||
1585 | function redirect_to_lesson_module_taxonomy_to_course( ){ |
||
1594 | |||
1595 | /** |
||
1596 | * Completely remove the module menu item under lessons. |
||
1597 | * |
||
1598 | * This function is hooked into the admin_menu |
||
1599 | * |
||
1600 | * @since 1.8.0 |
||
1601 | * @return void |
||
1602 | */ |
||
1603 | View Code Duplication | public function remove_lessons_menu_model_taxonomy(){ |
|
1619 | |||
1620 | /** |
||
1621 | * Completely remove the second modules under courses |
||
1622 | * |
||
1623 | * This function is hooked into the admin_menu |
||
1624 | * |
||
1625 | * @since 1.8.0 |
||
1626 | * @return void |
||
1627 | */ |
||
1628 | View Code Duplication | public function remove_courses_menu_model_taxonomy(){ |
|
1644 | |||
1645 | /** |
||
1646 | * Determine the author of a module term term by looking at |
||
1647 | * the prefixed author id. This function will query the full term object. |
||
1648 | * Will return the admin user author could not be determined. |
||
1649 | * |
||
1650 | * @since 1.8.0 |
||
1651 | * |
||
1652 | * @param string $term_name |
||
1653 | * @return array $owners { type WP_User }. Empty array if none if found. |
||
1654 | */ |
||
1655 | public static function get_term_authors( $term_name ){ |
||
1683 | |||
1684 | /** |
||
1685 | * Looks at a term slug and figures out |
||
1686 | * which author created the slug. The author was |
||
1687 | * appended when the user saved the module term in the course edit |
||
1688 | * screen. |
||
1689 | * |
||
1690 | * @since 1.8.0 |
||
1691 | * |
||
1692 | * @param $slug |
||
1693 | * @return WP_User $author if no author is found or invalid term is passed the admin user will be returned. |
||
1694 | */ |
||
1695 | public static function get_term_author( $slug='' ){ |
||
1725 | |||
1726 | /** |
||
1727 | * Display the Sensei modules taxonomy terms metabox |
||
1728 | * |
||
1729 | * @since 1.8.0 |
||
1730 | * |
||
1731 | * @hooked into add_meta_box |
||
1732 | * |
||
1733 | * @param WP_Post $post Post object. |
||
1734 | */ |
||
1735 | public function course_module_metabox( $post ) { |
||
1785 | |||
1786 | |||
1787 | /** |
||
1788 | * Submits a new module term prefixed with the |
||
1789 | * the current author id. |
||
1790 | * |
||
1791 | * @since 1.8.0 |
||
1792 | */ |
||
1793 | public static function add_new_module_term( ) { |
||
1847 | |||
1848 | /** |
||
1849 | * Limit the course module metabox |
||
1850 | * term list to only those on courses belonging to current teacher. |
||
1851 | * |
||
1852 | * Hooked into 'get_terms' |
||
1853 | * |
||
1854 | * @since 1.8.0 |
||
1855 | */ |
||
1856 | public function filter_module_terms( $terms, $taxonomies, $args ){ |
||
1879 | |||
1880 | /** |
||
1881 | * For the selected items on a course module only return those |
||
1882 | * for the current user. This does not apply to admin and super admin users. |
||
1883 | * |
||
1884 | * hooked into get_object_terms |
||
1885 | * |
||
1886 | * @since 1.8.0 |
||
1887 | */ |
||
1888 | public function filter_course_selected_terms( $terms, $course_ids_array, $taxonomies ){ |
||
1914 | |||
1915 | /** |
||
1916 | * Filter the given terms and only return the |
||
1917 | * terms that belong to the given user id. |
||
1918 | * |
||
1919 | * @since 1.8.0 |
||
1920 | * @param $terms |
||
1921 | * @param $user_id |
||
1922 | * @return array |
||
1923 | */ |
||
1924 | public function filter_terms_by_owner( $terms, $user_id ){ |
||
1947 | |||
1948 | /** |
||
1949 | * Add the teacher name next to modules. Only works in Admin for Admin users. |
||
1950 | * This will not add name to terms belonging to admin user. |
||
1951 | * |
||
1952 | * Hooked into 'get_terms' |
||
1953 | * |
||
1954 | * @since 1.8.0 |
||
1955 | */ |
||
1956 | public function append_teacher_name_to_module( $terms, $taxonomies, $args ) |
||
1993 | |||
1994 | /** |
||
1995 | * Remove modules metabox that come by default |
||
1996 | * with the modules taxonomy. We are removing this as |
||
1997 | * we have created our own custom meta box. |
||
1998 | */ |
||
1999 | public static function remove_default_modules_box() { |
||
2004 | |||
2005 | /** |
||
2006 | * When a course is save make sure to reset the transient set |
||
2007 | * for it when determining the none module lessons. |
||
2008 | * |
||
2009 | * @sine 1.9.0 |
||
2010 | * @param $post_id |
||
2011 | */ |
||
2012 | public static function reset_none_modules_transient ( $post_id ){ |
||
2035 | |||
2036 | /** |
||
2037 | * This function calls the deprecated hook 'sensei_single_course_modules_content' to fire |
||
2038 | * |
||
2039 | * @since 1.9.0 |
||
2040 | * @deprecated since 1.9.0 |
||
2041 | * |
||
2042 | */ |
||
2043 | public static function deprecate_sensei_single_course_modules_content(){ |
||
2048 | |||
2049 | /** |
||
2050 | * Setup the single course module loop. |
||
2051 | * |
||
2052 | * Setup the global $sensei_modules_loop |
||
2053 | * |
||
2054 | * @since 1.9.0 |
||
2055 | */ |
||
2056 | public static function setup_single_course_module_loop(){ |
||
2090 | |||
2091 | /** |
||
2092 | * Tear down the course module loop. |
||
2093 | * |
||
2094 | * @since 1.9.0 |
||
2095 | * |
||
2096 | */ |
||
2097 | public static function teardown_single_course_module_loop(){ |
||
2110 | |||
2111 | } // end modules class |
||
2112 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.