Passed
Push — master ( 4224ed...e7f15b )
by Paul
04:26
created

ListTableController   B

Complexity

Total Complexity 51

Size/Duplication

Total Lines 306
Duplicated Lines 0 %

Test Coverage

Coverage 7.58%

Importance

Changes 0
Metric Value
dl 0
loc 306
ccs 10
cts 132
cp 0.0758
rs 7.92
c 0
b 0
f 0
wmc 51

20 Methods

Rating   Name   Duplication   Size   Complexity  
A filterDateColumnStatus() 0 6 2
A setQueryForColumn() 0 7 2
A saveBulkEditFields() 0 6 4
A filterDefaultHiddenColumns() 0 6 2
A renderColumnValues() 0 3 1
A getTranslation() 0 13 2
A filterColumnsForPostType() 0 11 5
A setOrderby() 0 8 2
A setMetaQuery() 0 10 3
A filterSortableColumns() 0 9 3
A renderBulkEditFields() 0 4 3
A renderColumnFilters() 0 3 1
A hasPermission() 0 7 4
A approve() 0 9 1
A filterBulkUpdateMessages() 0 10 1
A unapprove() 0 9 1
A filterPostStates() 0 6 3
A filterRowActions() 0 22 4
A filterStatusText() 0 17 4
A canModifyTranslation() 0 6 3

How to fix   Complexity   

Complex Class

Complex classes like ListTableController 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.

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 ListTableController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace GeminiLabs\SiteReviews\Controllers;
4
5
use GeminiLabs\SiteReviews\Application;
6
use GeminiLabs\SiteReviews\Controllers\Controller;
7
use GeminiLabs\SiteReviews\Controllers\ListTableController\Columns;
8
use GeminiLabs\SiteReviews\Database;
9
use GeminiLabs\SiteReviews\Helper;
10
use GeminiLabs\SiteReviews\Modules\Html;
11
use GeminiLabs\SiteReviews\Modules\Html\Builder;
12
use WP_Post;
13
use WP_Query;
14
use WP_Screen;
15
16
class ListTableController extends Controller
17
{
18
	/**
19
	 * @return void
20
	 * @action admin_action_approve
21
	 */
22
	public function approve()
23
	{
24
		check_admin_referer( 'approve-review_'.( $postId = $this->getPostId() ));
25
		wp_update_post([
26
			'ID' => $postId,
27
			'post_status' => 'publish',
28
		]);
29
		wp_safe_redirect( wp_get_referer() );
30
		exit;
31
	}
32
33
	/**
34
	 * @return array
35
	 * @filter bulk_post_updated_messages
36
	 */
37
	public function filterBulkUpdateMessages( array $messages, array $counts )
38
	{
39
		$messages[Application::POST_TYPE] = [
40
			'updated' => _n( '%s review updated.', '%s reviews updated.', $counts['updated'], 'site-reviews' ),
41
			'locked' => _n( '%s review not updated, somebody is editing it.', '%s reviews not updated, somebody is editing them.', $counts['locked'], 'site-reviews' ),
42
			'deleted' => _n( '%s review permanently deleted.', '%s reviews permanently deleted.', $counts['deleted'], 'site-reviews' ),
43
			'trashed' => _n( '%s review moved to the Trash.', '%s reviews moved to the Trash.', $counts['trashed'], 'site-reviews' ),
44
			'untrashed' => _n( '%s review restored from the Trash.', '%s reviews restored from the Trash.', $counts['untrashed'], 'site-reviews' ),
45
		];
46
		return $messages;
47
	}
48
49
	/**
50
	 * @return array
51
	 * @filter manage_.Application::POST_TYPE._posts_columns
52
	 */
53
	public function filterColumnsForPostType( array $columns )
54
	{
55
		$postTypeColumns = glsr()->postTypeColumns[Application::POST_TYPE];
56
		foreach( $postTypeColumns as $key => &$value ) {
57
			if( !array_key_exists( $key, $columns ) || !empty( $value ))continue;
58
			$value = $columns[$key];
59
		}
60
		if( count( glsr( Database::class )->getReviewsMeta( 'type' )) < 2 ) {
61
			unset( $postTypeColumns['review_type'] );
62
		}
63
		return array_filter( $postTypeColumns, 'strlen' );
64
	}
65
66
	/**
67
	 * @param string $status
68
	 * @return string
69
	 * @filter post_date_column_status
70
	 */
71
	public function filterDateColumnStatus( $status, WP_Post $post )
72
	{
73
		if( $post->post_type == Application::POST_TYPE ) {
74
			$status = __( 'Submitted', 'site-reviews' );
75
		}
76
		return $status;
77
	}
78
79
	/**
80
	 * @return array
81
	 * @filter default_hidden_columns
82
	 */
83
	public function filterDefaultHiddenColumns( array $hidden, WP_Screen $screen )
84
	{
85
		if( $screen->id == 'edit-'.Application::POST_TYPE ) {
86
			$hidden = ['reviewer'];
87
		}
88
		return $hidden;
89
	}
90
91
	/**
92
	 * @return array
93
	 * @filter display_post_states
94
	 */
95
	public function filterPostStates( array $postStates, WP_Post $post ) {
96
		if( $post->post_type == Application::POST_TYPE
97
			&& array_key_exists( 'pending', $postStates )) {
98
			$postStates['pending'] = __( 'Unapproved', 'site-reviews' );
99
		}
100
		return $postStates;
101
	}
102
103
	/**
104
	 * @return array
105
	 * @filter post_row_actions
106
	 */
107
	public function filterRowActions( array $actions, WP_Post $post )
108
	{
109
		if( $post->post_type != Application::POST_TYPE || $post->post_status == 'trash' ) {
110
			return $actions;
111
		}
112
		unset( $actions['inline hide-if-no-js'] ); //Remove Quick-edit
113
		$rowActions = [
114
			'approve' => esc_attr__( 'Approve', 'site-reviews' ),
115
			'unapprove' => esc_attr__( 'Unapprove', 'site-reviews' ),
116
		];
117
		$newActions = [];
118
		foreach( $rowActions as $key => $text ) {
119
			$newActions[$key] = glsr( Builder::class )->a( $text, [
120
				'aria-label' => sprintf( esc_attr_x( '%s this review', 'Approve the review', 'site-reviews' ), $text ),
121
				'class' => 'glsr-change-status',
122
				'href' => wp_nonce_url(
123
					admin_url( 'post.php?post='.$post->ID.'&action='.$key ),
124
					$key.'-review_'.$post->ID
125
				),
126
			]);
127
		}
128
		return $newActions + $actions;
129
	}
130
131
	/**
132
	 * @return array
133
	 * @filter manage_edit-.Application::POST_TYPE._sortable_columns
134
	 */
135
	public function filterSortableColumns( array $columns )
136
	{
137
		$postTypeColumns = glsr()->postTypeColumns[Application::POST_TYPE];
138
		unset( $postTypeColumns['cb'] );
139
		foreach( $postTypeColumns as $key => $value ) {
140
			if( glsr( Helper::class )->startsWith( 'taxonomy', $key ))continue;
141
			$columns[$key] = $key;
142
		}
143
		return $columns;
144
	}
145
146
	/**
147
	 * Customize the post_type status text
148
	 * @param string $translation
149
	 * @param string $single
150
	 * @param string $plural
151
	 * @param int $number
152
	 * @param string $domain
153
	 * @return string
154
	 * @filter ngettext
155
	 */
156
	public function filterStatusText( $translation, $single, $plural, $number, $domain )
157
	{
158
		if( $this->canModifyTranslation( $domain )) {
159
			$strings = [
160
				'Published' => __( 'Approved', 'site-reviews' ),
161
				'Pending' => __( 'Unapproved', 'site-reviews' ),
162
			];
163
			foreach( $strings as $search => $replace ) {
164
				if( strpos( $single, $search ) === false )continue;
165
				$translation = $this->getTranslation([
166
					'number' => $number,
167
					'plural' => str_replace( $search, $replace, $plural ),
168
					'single' => str_replace( $search, $replace, $single ),
169
				]);
170
			}
171
		}
172
		return $translation;
173
	}
174
175
	/**
176
	 * @param string $columnName
177
	 * @param string $postType
178
	 * @return void
179
	 * @action bulk_edit_custom_box
180
	 */
181
	public function renderBulkEditFields( $columnName, $postType )
182
	{
183
		if( $columnName == 'assigned_to' && $postType == Application::POST_TYPE ) {
184
			glsr()->render( 'partials/editor/bulk-edit-assigned-to' );
185
		};
186
	}
187
188
	/**
189
	 * @param string $postType
190
	 * @return void
191
	 * @action restrict_manage_posts
192
	 */
193
	public function renderColumnFilters( $postType )
194
	{
195
		glsr( Columns::class )->renderFilters( $postType );
196
	}
197
198
	/**
199
	 * @param string $column
200
	 * @param string $postId
201
	 * @return void
202
	 * @action manage_posts_custom_column
203
	 */
204
	public function renderColumnValues( $column, $postId )
205
	{
206
		glsr( Columns::class )->renderValues( $column, $postId );
207
	}
208
209
	/**
210
	 * @param int $postId
211
	 * @return void
212
	 * @action save_post_.Application::POST_TYPE
213
	 */
214 1
	public function saveBulkEditFields( $postId )
215
	{
216 1
		if( !current_user_can( 'edit_posts' ))return;
217
		$assignedTo = filter_input( INPUT_GET, 'assigned_to' );
218
		if( $assignedTo && get_post( $assignedTo )) {
219
			update_post_meta( $postId, 'assigned_to', $assignedTo );
220
		}
221
	}
222
223
	/**
224
	 * @return void
225
	 * @action pre_get_posts
226
	 */
227 1
	public function setQueryForColumn( WP_Query $query )
228
	{
229 1
		if( !$this->hasPermission( $query ))return;
230
		$this->setMetaQuery( $query, [
231
			'rating', 'review_type',
232
		]);
233
		$this->setOrderby( $query );
234
	}
235
236
	/**
237
	 * @return void
238
	 * @action admin_action_unapprove
239
	 */
240
	public function unapprove()
241
	{
242
		check_admin_referer( 'unapprove-review_'.( $postId = $this->getPostId() ));
243
		wp_update_post([
244
			'ID' => $postId,
245
			'post_status' => 'pending',
246
		]);
247
		wp_safe_redirect( wp_get_referer() );
248
		exit;
249
	}
250
251
	/**
252
	 * Check if the translation string can be modified
253
	 * @param string $domain
254
	 * @return bool
255
	 */
256
	protected function canModifyTranslation( $domain = 'default' )
257
	{
258
		$screen = glsr_current_screen();
259
		return $domain == 'default'
260
			&& $screen->base == 'edit'
261
			&& $screen->post_type == Application::POST_TYPE;
262
	}
263
264
	/**
265
	 * Get the modified translation string
266
	 * @return string
267
	 */
268
	protected function getTranslation( array $args )
269
	{
270
		$defaults = [
271
			'number' => 0,
272
			'plural' => '',
273
			'single' => '',
274
			'text' => '',
275
		];
276
		$args = (object) wp_parse_args( $args, $defaults );
277
		$translations = get_translations_for_domain( Application::ID );
278
		return $args->text
279
			? $translations->translate( $args->text )
280
			: $translations->translate_plural( $args->single, $args->plural, $args->number );
281
	}
282
283
	/**
284
	 * @return bool
285
	 */
286 1
	protected function hasPermission( WP_Query $query )
287
	{
288 1
		global $pagenow;
289 1
		return is_admin()
290 1
			&& $query->is_main_query()
291 1
			&& $query->get( 'post_type' ) == Application::POST_TYPE
292 1
			&& $pagenow == 'edit.php';
293
	}
294
295
	/**
296
	 * @return void
297
	 */
298
	protected function setMetaQuery( WP_Query $query, array $metaKeys )
299
	{
300
		foreach( $metaKeys as $key ) {
301
			if( !( $value = filter_input( INPUT_GET, $key )))continue;
302
			$metaQuery = (array)$query->get( 'meta_query' );
303
			$metaQuery[] = [
304
				'key' => $key,
305
				'value' => $value,
306
			];
307
			$query->set( 'meta_query', $metaQuery );
308
		}
309
	}
310
311
	/**
312
	 * @return void
313
	 */
314
	protected function setOrderby( WP_Query $query )
315
	{
316
		$orderby = $query->get( 'orderby' );
317
		$columns = glsr()->postTypeColumns[Application::POST_TYPE];
318
		unset( $columns['cb'], $columns['title'], $columns['date'] );
319
		if( in_array( $orderby, array_keys( $columns ))) {
320
			$query->set( 'meta_key', $orderby );
321
			$query->set( 'orderby', 'meta_value' );
322
		}
323
	}
324
}
325