PluginProbe
wpForo Forum / 3.1.6
wpForo Forum v3.1.6
3.1.6 3.1.5 3.1.4 3.1.2 3.1.1 3.1.0 3.0.9 3.0.8 3.0.7 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 1.4.13 All 138 releases
wpforo / admin / listtables / Phrases.php

Phrases.php in wpForo Forum 3.1.6, at admin/listtables/Phrases.php

312 lines 14.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace wpforo\admin\listtables;
4
5 use WP_List_Table;
6
7 require_once( ABSPATH . 'wp-admin/includes/template.php' );
8 require_once( ABSPATH . 'wp-admin/includes/screen.php' );
9 require_once( ABSPATH . 'wp-admin/includes/class-wp-screen.php' );
10 require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
11
12 class Phrases extends WP_List_Table {
13
14 public $wpfitems_count;
15
16 /** ************************************************************************
17 * REQUIRED. Set up a constructor that references the parent constructor. We
18 * use the parent reference to set some default configs.
19 ***************************************************************************/
20 function __construct() {
21 //Set parent defaults
22 parent::__construct( [
23 'singular' => 'phrase', //singular name of the listed records
24 'plural' => 'phrases', //plural name of the listed records
25 'ajax' => false, //does this table support ajax?
26 'screen' => 'wpForoPhrases',
27 ] );
28
29 }
30
31
32 /** ************************************************************************
33 * Recommended. This method is called when the parent class can't find a method
34 * specifically build for a given column. Generally, it's recommended to include
35 * one method for each column you want to render, keeping your package class
36 * neat and organized. For example, if the class needs to process a column
37 * named 'title', it would first see if a method named $this->column_title()
38 * exists - if it does, that method will be used. If it doesn't, this one will
39 * be used. Generally, you should try to use custom column methods as much as
40 * possible.
41 *
42 * Since we have defined a column_title() method later on, this method doesn't
43 * need to concern itself with any column with a name of 'title'. Instead, it
44 * needs to handle everything else.
45 *
46 * For more detailed insight into how columns are handled, take a look at
47 * WP_List_Table::single_row_columns()
48 *
49 * @param array $item A singular item (one full row's worth of data)
50 * @param string $column_name The name/slug of the column to be processed
51 *
52 * @return string Text or HTML to be placed inside the column <td>
53 **************************************************************************/
54 function column_default( $item, $column_name ) {
55 switch( $column_name ) {
56 case 'langid':
57 $language = WPF()->phrase->get_language( $item[ $column_name ] );
58
59 return ( ! empty( $language['name'] ) ? esc_html( $language['name'] ) : __( 'default', 'wpforo' ) );
60 default:
61 return $item[ $column_name ];
62 }
63 }
64
65
66 /** ************************************************************************
67 * Recommended. This is a custom column method and is responsible for what
68 * is rendered in any column with a name/slug of 'title'. Every time the class
69 * needs to render a column, it first looks for a method named
70 * column_{$column_title} - if it exists, that method is run. If it doesn't
71 * exist, column_default() is called instead.
72 *
73 * This example also illustrates how to implement rollover actions. Actions
74 * should be an associative array formatted as 'slug'=>'link html' - and you
75 * will need to generate the URLs yourself. You could even ensure the links
76 *
77 *
78 * @param array $item A singular item (one full row's worth of data)
79 *
80 * @return string Text to be placed inside the column <td> (movie title only)
81 **************************************************************************@see WP_List_Table::::single_row_columns()
82 */
83 function column_phraseid( $item ) {
84 $ehref = wp_nonce_url(
85 admin_url( sprintf( 'admin.php?page=%1$s&wpfaction=%2$s&phraseid=%3$s', wpforo_prefix_slug( 'phrases' ), 'phrase_edit_form', $item['phraseid'] ) ),
86 'wpforo-phrase-edit-' . $item['phraseid']
87 );
88 $actions = [
89 'edit' => '<a href="' . $ehref . '">' . __( 'Edit', 'wpforo' ) . '</a>',
90 ];
91
92 //Return the title contents
93 return sprintf(
94 '%1$s %2$s',
95 /*$1%s*/ $item['phraseid'],
96 /*$2%s*/ $this->row_actions( $actions )
97 );
98 }
99
100
101 /** ************************************************************************
102 * REQUIRED if displaying checkboxes or using bulk actions! The 'cb' column
103 * is given special treatment when columns are processed. It ALWAYS needs to
104 * have its own method.
105 *
106 * @param array $item A singular item (one full row's worth of data)
107 *
108 * @return string Text to be placed inside the column <td> (movie title only)
109 **************************************************************************@see WP_List_Table::::single_row_columns()
110 */
111 function column_cb( $item ) {
112 return sprintf(
113 '<input type="checkbox" name="%1$s[]" value="%2$s" />',
114 /*$1%s*/ 'phraseids', //Let's simply repurpose the table's singular label ("movie")
115 /*$2%s*/ $item['phraseid'] //The value of the checkbox should be the record's id
116 );
117 }
118
119
120 /** ************************************************************************
121 * REQUIRED! This method dictates the table's columns and titles. This should
122 * return an array where the key is the column slug (and class) and the value
123 * is the column's title text. If you need a checkbox for bulk actions, refer
124 * to the $columns array below.
125 *
126 * The 'cb' column is treated differently than the rest. If including a checkbox
127 * column in your table you must create a column_cb() method. If you don't need
128 * to bulk actions or checkboxes, simply leave the 'cb' entry out of your array.
129 *
130 * @return array An associative array containing column information: 'slugs'=>'Visible Titles'
131 **************************************************************************@see WP_List_Table::::single_row_columns()
132 */
133 function get_columns() {
134 return [
135 'cb' => '<input type="checkbox" />', //Render a checkbox instead of text
136 'phraseid' => __( 'ID', 'wpforo' ),
137 'phrase_key' => __( 'Original', 'wpforo' ),
138 'phrase_value' => __( 'Translation', 'wpforo' ),
139 'package' => __( 'Package', 'wpforo' ),
140 'langid' => __( 'Language', 'wpforo' ),
141 ];
142 }
143
144
145 /** ************************************************************************
146 * Optional. If you want one or more columns to be sortable (ASC/DESC toggle),
147 * you will need to register it here. This should return an array where the
148 * key is the column that needs to be sortable, and the value is db column to
149 * sort by. Often, the key and value will be the same, but this is not always
150 * the case (as the value is a column name from the database, not the list table).
151 *
152 * This method merely defines which columns should be sortable and makes them
153 * clickable - it does not handle the actual sorting. You still need to detect
154 * the ORDERBY and ORDER querystring variables within prepare_items() and sort
155 * your data accordingly (usually by modifying your query).
156 *
157 * @return array An associative array containing all the columns that should be sortable: 'slugs'=>array('data_values',bool)
158 **************************************************************************/
159 function get_sortable_columns() {
160 return [
161 'phraseid' => [ 'phraseid', false ], //true means it's already sorted
162 'phrase_key' => [ 'phrase_key', false ],
163 'phrase_value' => [ 'phrase_value', false ],
164 'package' => [ 'package', false ],
165 'langid' => [ 'langid', false ],
166 ];
167 }
168
169
170 /** ************************************************************************
171 * Optional. If you need to include bulk actions in your list table, this is
172 * the place to define them. Bulk actions are an associative array in the format
173 * 'slug'=>'Visible Title'
174 *
175 * If this method returns an empty value, no bulk action will be rendered. If
176 * you specify any bulk actions, the bulk actions box will be rendered with
177 * the table automatically on display().
178 *
179 * Also note that list tables are not automatically wrapped in <form> elements,
180 * so you will need to create those manually in order for bulk actions to function.
181 *
182 * @return array An associative array containing all the bulk actions: 'slugs'=>'Visible Titles'
183 **************************************************************************/
184 function get_bulk_actions() {
185 return [ 'edit' => __( 'Edit', 'wpforo' ) ];
186 }
187
188
189 /** ************************************************************************
190 * REQUIRED! This is where you prepare your data for display. This method will
191 * usually be used to query the database, sort and filter the data, and generally
192 * get it ready to be displayed. At a minimum, we should set $this->items and
193 * $this->set_pagination_args(), although the following properties and methods
194 * are frequently interacted with here...
195 *
196 * @uses $this->_column_headers
197 * @uses $this->items
198 * @uses $this->get_columns()
199 * @uses $this->get_sortable_columns()
200 * @uses $this->get_pagenum()
201 * @uses $this->set_pagination_args()
202 **************************************************************************/
203 function prepare_items() {
204 /**
205 * First, lets decide how many records per page to show
206 */
207 $per_page = wpforo_get_option( 'count_per_page', 10 );
208
209
210 /**
211 * REQUIRED. Now we need to define our column headers. This includes a complete
212 * array of columns to be displayed (slugs & titles), a list of columns
213 * to keep hidden, and a list of columns that are sortable. Each of these
214 * can be defined in another method (as we've done here) before being
215 * used to build the value for our _column_headers property.
216 */
217 $columns = $this->get_columns();
218 $hidden = [];
219 $sortable = $this->get_sortable_columns();
220
221
222 /**
223 * REQUIRED. Finally, we build an array to be used by the class for column
224 * headers. The $this->_column_headers property takes an array which contains
225 * 3 other arrays. One for all columns, one for hidden columns, and one
226 * for sortable columns.
227 */
228 $this->_column_headers = [ $columns, $hidden, $sortable ];
229
230 /**
231 * REQUIRED. Now we can add our *sorted* data to the items' property, where
232 * it can be used by the rest of the class.
233 */
234 $args = [ 'langid' => $this->get_filter_by_langid_var() ];
235 if( $s = wpfval( $_REQUEST, 's' ) ) $args['include'] = WPF()->phrase->search( $s );
236 $orderby = (string) wpfval( $_REQUEST, 'orderby' );
237 $order = strtoupper( (string) wpfval( $_REQUEST, 'order' ) );
238 $filter_by_package = $this->get_filter_by_package_var();
239 if( $filter_by_package !== - 1 ) $args['package'] = (array) $filter_by_package;
240 if( in_array( $order, [ 'ASC', 'DESC' ] ) ) $args['order'] = sanitize_text_field( $order );
241 if( array_key_exists( $orderby, $sortable ) ) $args['orderby'] = sanitize_text_field( $orderby );
242
243 $paged = $this->get_pagenum();
244 $args['offset'] = ( $paged - 1 ) * $per_page;
245 $args['row_count'] = $per_page;
246
247 $items_count = 0;
248 $this->items = ( isset( $args['include'] ) && empty( $args['include'] ) ? [] : WPF()->phrase->get_phrases( $args, $items_count, true ) );
249
250 $this->wpfitems_count = $items_count;
251
252 $this->set_pagination_args( [
253 'total_items' => $items_count, //WE have to calculate the total number of items
254 'per_page' => $per_page, //WE have to determine how many items to show on a page
255 'total_pages' => ceil( $items_count / $per_page ), //WE have to calculate the total number of pages
256 ] );
257 }
258
259 public function get_filter_by_langid_var() {
260 $filter_by_langid = wpfval( $_REQUEST, 'filter_by_langid' );
261 if( ! is_null( $filter_by_langid ) && $filter_by_langid !== '-1' ) {
262 $langid = $filter_by_langid;
263 } else {
264 $langid = WPF()->phrase->langid;
265 }
266
267 return intval( $langid );
268 }
269
270 public function get_filter_by_package_var() {
271 $filter_by_package = wpfval( $_REQUEST, 'filter_by_package' );
272 if( ! is_null( $filter_by_package ) && $filter_by_package !== '-1' ) {
273 $package = $filter_by_package;
274 } else {
275 $package = - 1;
276 }
277
278 return $package;
279 }
280
281 public function packages_dropdown() { ?>
282 <label>
283 <select name="filter_by_package">
284 <option value="-1">-- <?php _e( 'filter by package', 'wpforo' ) ?> --</option>
285 <?php
286 if( $packages = WPF()->phrase->get_distinct_packages() ) {
287 $selected = $this->get_filter_by_package_var();
288 foreach( $packages as $package ) {
289 printf(
290 '<option value="%1$s" %2$s>%3$s</option>',
291 esc_attr( $package ),
292 ( $package === $selected ) ? 'selected' : '',
293 esc_html( $package )
294 );
295 }
296 }
297 ?>
298 </select>
299 </label>
300 <?php
301 }
302
303 public function languages_dropdown() { ?>
304 <label>
305 <select name="filter_by_langid">
306 <?php WPF()->phrase->show_lang_list( $this->get_filter_by_langid_var() ); ?>
307 </select>
308 </label>
309 <?php
310 }
311 }
312