PageRenderTime 54ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/woothemes-sensei/includes/class-sensei-analysis-lesson-list-table.php

https://gitlab.com/ezgonzalez/integral
PHP | 357 lines | 215 code | 54 blank | 88 comment | 27 complexity | f317e7ae93f0fd7df66e61639950f93a MD5 | raw file
  1. <?php
  2. if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
  3. /**
  4. * Admin Analysis Lesson Data Table in Sensei.
  5. *
  6. * @package Analytics
  7. * @author Automattic
  8. *
  9. * @since 1.2.0
  10. */
  11. class Sensei_Analysis_Lesson_List_Table extends WooThemes_Sensei_List_Table {
  12. public $lesson_id;
  13. public $course_id;
  14. public $page_slug = 'sensei_analysis';
  15. /**
  16. * Constructor
  17. * @since 1.2.0
  18. */
  19. public function __construct ( $lesson_id = 0 ) {
  20. $this->lesson_id = intval( $lesson_id );
  21. $this->course_id = intval( get_post_meta( $this->lesson_id, '_lesson_course', true ) );
  22. // Load Parent token into constructor
  23. parent::__construct( 'analysis_lesson' );
  24. // Actions
  25. add_action( 'sensei_before_list_table', array( $this, 'data_table_header' ) );
  26. add_action( 'sensei_after_list_table', array( $this, 'data_table_footer' ) );
  27. add_filter( 'sensei_list_table_search_button_text', array( $this, 'search_button' ) );
  28. } // End __construct()
  29. /**
  30. * Define the columns that are going to be used in the table
  31. * @since 1.7.0
  32. * @return array $columns, the array of columns to use with the table
  33. */
  34. function get_columns() {
  35. $columns = array(
  36. 'title' => __( 'Learner', 'woothemes-sensei' ),
  37. 'started' => __( 'Date Started', 'woothemes-sensei' ),
  38. 'completed' => __( 'Date Completed', 'woothemes-sensei' ),
  39. 'status' => __( 'Status', 'woothemes-sensei' ),
  40. 'grade' => __( 'Grade', 'woothemes-sensei' ),
  41. );
  42. $columns = apply_filters( 'sensei_analysis_lesson_columns', $columns, $this );
  43. return $columns;
  44. }
  45. /**
  46. * get_columns Define the columns that are going to be used in the table
  47. * @since 1.7.0
  48. * @return array $columns, the array of columns to use with the table
  49. */
  50. function get_sortable_columns() {
  51. $columns = array(
  52. 'title' => array( 'title', false ),
  53. 'started' => array( 'started', false ),
  54. 'completed' => array( 'completed', false ),
  55. 'status' => array( 'status', false ),
  56. 'grade' => array( 'grade', false ),
  57. );
  58. $columns = apply_filters( 'sensei_analysis_lesson_columns_sortable', $columns, $this );
  59. return $columns;
  60. }
  61. /**
  62. * Prepare the table with different parameters, pagination, columns and table elements
  63. * @since 1.7.0
  64. * @return void
  65. */
  66. public function prepare_items() {
  67. global $per_page;
  68. // Handle orderby (needs work)
  69. $orderby = '';
  70. if ( !empty( $_GET['orderby'] ) ) {
  71. if ( array_key_exists( esc_html( $_GET['orderby'] ), $this->get_sortable_columns() ) ) {
  72. $orderby = esc_html( $_GET['orderby'] );
  73. } // End If Statement
  74. }
  75. // Handle order
  76. $order = 'ASC';
  77. if ( !empty( $_GET['order'] ) ) {
  78. $order = ( 'ASC' == strtoupper($_GET['order']) ) ? 'ASC' : 'DESC';
  79. }
  80. // Handle search, need 4.1 version of WP to be able to restrict statuses to known post_ids
  81. $search = false;
  82. if ( !empty( $_GET['s'] ) ) {
  83. $search = esc_html( $_GET['s'] );
  84. } // End If Statement
  85. $this->search = $search;
  86. $per_page = $this->get_items_per_page( 'sensei_comments_per_page' );
  87. $per_page = apply_filters( 'sensei_comments_per_page', $per_page, 'sensei_comments' );
  88. $paged = $this->get_pagenum();
  89. $offset = 0;
  90. if ( !empty($paged) ) {
  91. $offset = $per_page * ( $paged - 1 );
  92. } // End If Statement
  93. $args = array(
  94. 'number' => $per_page,
  95. 'offset' => $offset,
  96. 'orderby' => $orderby,
  97. 'order' => $order,
  98. );
  99. if ( $this->search ) {
  100. $args['search'] = $this->search;
  101. } // End If Statement
  102. $this->items = $this->get_lesson_statuses( $args );
  103. $total_items = $this->total_items;
  104. $total_pages = ceil( $total_items / $per_page );
  105. $this->set_pagination_args( array(
  106. 'total_items' => $total_items,
  107. 'total_pages' => $total_pages,
  108. 'per_page' => $per_page
  109. ) );
  110. }
  111. /**
  112. * Generate a csv report with different parameters, pagination, columns and table elements
  113. * @since 1.7.0
  114. * @return data
  115. */
  116. public function generate_report( $report ) {
  117. $data = array();
  118. $this->csv_output = true;
  119. // Handle orderby
  120. $orderby = '';
  121. if ( !empty( $_GET['orderby'] ) ) {
  122. if ( array_key_exists( esc_html( $_GET['orderby'] ), $this->get_sortable_columns() ) ) {
  123. $orderby = esc_html( $_GET['orderby'] );
  124. } // End If Statement
  125. }
  126. // Handle order
  127. $order = 'ASC';
  128. if ( !empty( $_GET['order'] ) ) {
  129. $order = ( 'ASC' == strtoupper($_GET['order']) ) ? 'ASC' : 'DESC';
  130. }
  131. // Handle search
  132. $search = false;
  133. if ( !empty( $_GET['s'] ) ) {
  134. $search = esc_html( $_GET['s'] );
  135. } // End If Statement
  136. $this->search = $search;
  137. $args = array(
  138. 'orderby' => $orderby,
  139. 'order' => $order,
  140. );
  141. if ( $this->search ) {
  142. $args['search'] = $this->search;
  143. } // End If Statement
  144. // Start the csv with the column headings
  145. $column_headers = array();
  146. $columns = $this->get_columns();
  147. foreach( $columns AS $key => $title ) {
  148. $column_headers[] = $title;
  149. }
  150. $data[] = $column_headers;
  151. $this->items = $this->get_lesson_statuses( $args );
  152. // Process each row
  153. foreach( $this->items AS $item) {
  154. $data[] = $this->get_row_data( $item );
  155. }
  156. return $data;
  157. }
  158. /**
  159. * Generates the overall array for a single item in the display
  160. *
  161. * @since 1.7.0
  162. * @param object $item The current item
  163. */
  164. protected function get_row_data( $item ) {
  165. $user_start_date = get_comment_meta( $item->comment_ID, 'start', true );
  166. $user_end_date = $item->comment_date;
  167. $status_class = $grade = '';
  168. if( 'complete' == $item->comment_approved ) {
  169. $status = __( 'Completed', 'woothemes-sensei' );
  170. $status_class = 'graded';
  171. $grade = __( 'No Grade', 'woothemes-sensei' );
  172. }
  173. elseif( 'graded' == $item->comment_approved ) {
  174. $status = __( 'Graded', 'woothemes-sensei' ) ;
  175. $status_class = 'graded';
  176. $grade = get_comment_meta( $item->comment_ID, 'grade', true);
  177. }
  178. elseif( 'passed' == $item->comment_approved ) {
  179. $status = __( 'Passed', 'woothemes-sensei' );
  180. $status_class = 'graded';
  181. $grade = get_comment_meta( $item->comment_ID, 'grade', true);
  182. }
  183. elseif( 'failed' == $item->comment_approved ) {
  184. $status = __( 'Failed', 'woothemes-sensei' );
  185. $status_class = 'failed';
  186. $grade = get_comment_meta( $item->comment_ID, 'grade', true);
  187. }
  188. elseif( 'ungraded' == $item->comment_approved ) {
  189. $status = __( 'Ungraded', 'woothemes-sensei' );
  190. $status_class = 'ungraded';
  191. }
  192. else {
  193. $status = __( 'In Progress', 'woothemes-sensei' );
  194. $user_end_date = '';
  195. }
  196. // Output users data
  197. $user_name = Sensei_Learner::get_full_name( $item->user_id );
  198. if ( !$this->csv_output ) {
  199. $url = add_query_arg( array( 'page' => $this->page_slug, 'user_id' => $item->user_id, 'course_id' => $this->course_id ), admin_url( 'admin.php' ) );
  200. $user_name = '<strong><a class="row-title" href="' . esc_url( $url ) . '">' . $user_name . '</a></strong>';
  201. $status = sprintf( '<span class="%s">%s</span>', $item->comment_approved, $status );
  202. if ( is_numeric($grade) ) {
  203. $grade .= '%';
  204. }
  205. } // End If Statement
  206. $column_data = apply_filters( 'sensei_analysis_lesson_column_data', array( 'title' => $user_name,
  207. 'started' => $user_start_date,
  208. 'completed' => $user_end_date,
  209. 'status' => $status,
  210. 'grade' => $grade,
  211. ), $item, $this );
  212. return $column_data;
  213. }
  214. /**
  215. * Return array of lesson statuses
  216. * @since 1.7.0
  217. * @return array statuses
  218. */
  219. private function get_lesson_statuses( $args ) {
  220. $activity_args = array(
  221. 'post_id' => $this->lesson_id,
  222. 'type' => 'sensei_lesson_status',
  223. 'number' => $args['number'],
  224. 'offset' => $args['offset'],
  225. 'orderby' => $args['orderby'],
  226. 'order' => $args['order'],
  227. 'status' => 'any',
  228. );
  229. // Searching users on statuses requires sub-selecting the statuses by user_ids
  230. if ( $this->search ) {
  231. $user_args = array(
  232. 'search' => '*' . $this->search . '*',
  233. 'fields' => 'ID',
  234. );
  235. // Filter for extending
  236. $user_args = apply_filters( 'sensei_analysis_lesson_search_users', $user_args );
  237. if ( !empty( $user_args ) ) {
  238. $learners_search = new WP_User_Query( $user_args );
  239. // Store for reuse on counts
  240. $activity_args['user_id'] = (array) $learners_search->get_results();
  241. }
  242. } // End If Statement
  243. $activity_args = apply_filters( 'sensei_analysis_lesson_filter_statuses', $activity_args );
  244. // WP_Comment_Query doesn't support SQL_CALC_FOUND_ROWS, so instead do this twice
  245. $this->total_items = Sensei_Utils::sensei_check_for_activity( array_merge( $activity_args, array('count' => true, 'offset' => 0, 'number' => 0) ) );
  246. // Ensure we change our range to fit (in case a search threw off the pagination) - Should this be added to all views?
  247. if ( $this->total_items < $activity_args['offset'] ) {
  248. $new_paged = floor( $total_statuses / $activity_args['number'] );
  249. $activity_args['offset'] = $new_paged * $activity_args['number'];
  250. }
  251. $statuses = Sensei_Utils::sensei_check_for_activity( $activity_args, true );
  252. // Need to always return an array, even with only 1 item
  253. if ( !is_array($statuses) ) {
  254. $statuses = array( $statuses );
  255. }
  256. return $statuses;
  257. } // End get_lesson_statuses()
  258. /**
  259. * no_items sets output when no items are found
  260. * Overloads the parent method
  261. * @since 1.2.0
  262. * @return void
  263. */
  264. public function no_items() {
  265. _e( 'No learners found.', 'woothemes-sensei' );
  266. } // End no_items()
  267. /**
  268. * data_table_header output for table heading
  269. * @since 1.2.0
  270. * @return void
  271. */
  272. public function data_table_header() {
  273. echo '<strong>' . __( 'Learners taking this Lesson', 'woothemes-sensei' ) . '</strong>';
  274. } // End data_table_header()
  275. /**
  276. * data_table_footer output for table footer
  277. * @since 1.2.0
  278. * @return void
  279. */
  280. public function data_table_footer() {
  281. $lesson = get_post( $this->lesson_id );
  282. $report = sanitize_title( $lesson->post_title ) . '-learners-overview';
  283. $url = add_query_arg( array( 'page' => $this->page_slug, 'lesson_id' => $this->lesson_id, 'sensei_report_download' => $report ), admin_url( 'admin.php' ) );
  284. echo '<a class="button button-primary" href="' . esc_url( wp_nonce_url( $url, 'sensei_csv_download-' . $report, '_sdl_nonce' ) ) . '">' . __( 'Export all rows (CSV)', 'woothemes-sensei' ) . '</a>';
  285. } // End data_table_footer()
  286. /**
  287. * the text for the search button
  288. * @since 1.7.0
  289. * @return string $text
  290. */
  291. public function search_button( $text = '' ) {
  292. $text = __( 'Search Learners', 'woothemes-sensei' );
  293. return $text;
  294. }
  295. } // End Class
  296. /**
  297. * Class WooThemes_Sensei_Analysis_Lesson_List_Table
  298. *
  299. * @ignore only for backward compatibility
  300. * @since 1.9.0
  301. * @ignore
  302. */
  303. class WooThemes_Sensei_Analysis_Lesson_List_Table extends Sensei_Analysis_Lesson_List_Table {}