Completed
Push — master ( 1e1c87...a1ea0d )
by Stephanie
02:47
created

FrmFormsListHelper   D

Complexity

Total Complexity 58

Size/Duplication

Total Lines 357
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
dl 0
loc 357
rs 4.5599
c 0
b 0
f 0
wmc 58
lcom 1
cbo 6

13 Methods

Rating   Name   Duplication   Size   Complexity  
B get_bulk_actions() 0 19 7
A extra_tablenav() 0 13 4
A get_views() 0 35 5
A pagination() 0 9 2
F single_row() 0 85 17
A get_actions() 0 20 4
A get_form_name() 0 24 5
A add_draft_label() 0 5 3
A add_form_description() 0 6 2
A __construct() 0 5 1
B prepare_items() 0 85 5
A no_items() 0 15 2
A confirm_bulk_delete() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like FrmFormsListHelper 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 FrmFormsListHelper, and based on these observations, apply Extract Interface, too.

1
<?php
2
if ( ! defined( 'ABSPATH' ) ) {
3
	die( 'You are not allowed to call this page directly.' );
4
}
5
6
class FrmFormsListHelper extends FrmListHelper {
7
	public $status = '';
8
9
	public $total_items = 0;
10
11
	public function __construct( $args ) {
12
		$this->status = self::get_param( array( 'param' => 'form_type' ) );
0 ignored issues
show
Documentation Bug introduced by
It seems like self::get_param(array('param' => 'form_type')) can also be of type array. However, the property $status is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
13
14
		parent::__construct( $args );
15
	}
16
17
	public function prepare_items() {
18
		global $wpdb, $per_page, $mode;
19
20
		$page     = $this->get_pagenum();
21
		$per_page = $this->get_items_per_page( 'formidable_page_formidable_per_page' );
22
23
		$mode    = self::get_param(
24
			array(
25
				'param'   => 'mode',
26
				'default' => 'list',
27
			)
28
		);
29
		$orderby = self::get_param(
30
			array(
31
				'param'   => 'orderby',
32
				'default' => 'name',
33
			)
34
		);
35
		$order   = self::get_param(
36
			array(
37
				'param'   => 'order',
38
				'default' => 'ASC',
39
			)
40
		);
41
		$start   = self::get_param(
42
			array(
43
				'param'   => 'start',
44
				'default' => ( $page - 1 ) * $per_page,
45
			)
46
		);
47
48
		$s_query = array(
49
			array(
50
				'or'               => 1,
51
				'parent_form_id'   => null,
52
				'parent_form_id <' => 1,
53
			),
54
		);
55
		switch ( $this->status ) {
56
			case 'draft':
57
				$s_query['is_template'] = 0;
58
				$s_query['status']      = 'draft';
59
				break;
60
			case 'trash':
61
				$s_query['status'] = 'trash';
62
				break;
63
			default:
64
				$s_query['is_template'] = 0;
65
				$s_query['status !']    = 'trash';
66
				break;
67
		}
68
69
		$s = self::get_param(
70
			array(
71
				'param'    => 's',
72
				'sanitize' => 'sanitize_text_field',
73
			)
74
		);
75
		if ( $s != '' ) {
76
			preg_match_all( '/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $s, $matches );
77
			$search_terms = array_map( 'trim', $matches[0] );
78
			foreach ( (array) $search_terms as $term ) {
79
				$s_query[] = array(
80
					'or'               => true,
81
					'name LIKE'        => $term,
82
					'description LIKE' => $term,
83
					'created_at LIKE'  => $term,
84
					'form_key LIKE'    => $term,
85
					'id'               => $term,
86
				);
87
				unset( $term );
88
			}
89
		}
90
91
		$this->items = FrmForm::getAll( $s_query, $orderby . ' ' . $order, $start . ',' . $per_page );
0 ignored issues
show
Documentation Bug introduced by
It seems like \FrmForm::getAll($s_quer...tart . ',' . $per_page) can also be of type object. However, the property $items is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
92
		$total_items = FrmDb::get_count( 'frm_forms', $s_query );
93
		$this->total_items = $total_items;
94
95
		$this->set_pagination_args(
96
			array(
97
				'total_items' => $total_items,
98
				'per_page'    => $per_page,
99
			)
100
		);
101
	}
102
103
	public function no_items() {
104
		if ( $this->status === 'trash' ) {
105
			echo '<p>';
106
			esc_html_e( 'No forms found in the trash.', 'formidable' );
107
			?>
108
			<a href="<?php echo esc_url( admin_url( 'admin.php?page=formidable' ) ); ?>">
109
				<?php esc_html_e( 'See all forms.', 'formidable' ); ?>
110
			</a>
111
			<?php
112
			echo '</p>';
113
		} else {
114
			$title = __( 'No Forms Found', 'formidable' );
115
			include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/_no_forms.php';
116
		}
117
	}
118
119
	public function get_bulk_actions() {
120
		$actions = array();
121
122
		if ( 'trash' == $this->status ) {
123
			if ( current_user_can( 'frm_edit_forms' ) ) {
124
				$actions['bulk_untrash'] = __( 'Restore', 'formidable' );
125
			}
126
127
			if ( current_user_can( 'frm_delete_forms' ) ) {
128
				$actions['bulk_delete'] = __( 'Delete Permanently', 'formidable' );
129
			}
130
		} elseif ( EMPTY_TRASH_DAYS && current_user_can( 'frm_delete_forms' ) ) {
131
			$actions['bulk_trash'] = __( 'Move to Trash', 'formidable' );
132
		} elseif ( current_user_can( 'frm_delete_forms' ) ) {
133
			$actions['bulk_delete'] = __( 'Delete', 'formidable' );
134
		}
135
136
		return $actions;
137
	}
138
139
	public function extra_tablenav( $which ) {
140
		if ( 'top' != $which ) {
141
			return;
142
		}
143
144
		if ( 'trash' == $this->status && current_user_can( 'frm_delete_forms' ) ) {
145
			?>
146
			<div class="alignleft actions frm_visible_overflow">
147
				<?php submit_button( __( 'Empty Trash', 'formidable' ), 'apply', 'delete_all', false ); ?>
148
			</div>
149
			<?php
150
		}
151
	}
152
153
	public function get_views() {
154
155
		$statuses = array(
156
			'published' => __( 'My Forms', 'formidable' ),
157
			'draft'     => __( 'Drafts', 'formidable' ),
158
			'trash'     => __( 'Trash', 'formidable' ),
159
		);
160
161
		$links     = array();
162
		$counts    = FrmForm::get_count();
163
		$form_type = self::get_param(
164
			array(
165
				'param'   => 'form_type',
166
				'default' => 'published',
167
			)
168
		);
169
170
		foreach ( $statuses as $status => $name ) {
171
172
			if ( $status == $form_type ) {
173
				$class = ' class="current"';
174
			} else {
175
				$class = '';
176
			}
177
178
			if ( $counts->{$status} || 'draft' !== $status ) {
179
				/* translators: %1$s: Status, %2$s: Number of items */
180
				$links[ $status ] = '<a href="' . esc_url( '?page=formidable&form_type=' . $status ) . '" ' . $class . '>' . sprintf( __( '%1$s <span class="count">(%2$s)</span>', 'formidable' ), $name, number_format_i18n( $counts->{$status} ) ) . '</a>';
181
			}
182
183
			unset( $status, $name );
184
		}
185
186
		return $links;
187
	}
188
189
	public function pagination( $which ) {
190
		global $mode;
191
192
		parent::pagination( $which );
193
194
		if ( 'top' == $which ) {
195
			$this->view_switcher( $mode );
196
		}
197
	}
198
199
	public function single_row( $item, $style = '' ) {
200
		global $frm_vars, $mode;
201
202
		// Set up the hover actions for this user
203
		$actions   = array();
204
		$edit_link = FrmForm::get_edit_link( $item->id );
205
206
		$this->get_actions( $actions, $item, $edit_link );
207
208
		$action_links = $this->row_actions( $actions );
209
210
		// Set up the checkbox ( because the user is editable, otherwise its empty )
211
		$checkbox = '<input type="checkbox" name="item-action[]" id="cb-item-action-' . absint( $item->id ) . '" value="' . esc_attr( $item->id ) . '" />';
212
213
		$r = '<tr id="item-action-' . absint( $item->id ) . '"' . $style . '>';
214
215
		list( $columns, $hidden ) = $this->get_column_info();
216
217
		$format = 'Y/m/d';
218
		if ( 'list' != $mode ) {
219
			$format .= ' \<\b\r \/\> g:i:s a';
220
		}
221
222
		foreach ( $columns as $column_name => $column_display_name ) {
223
			$class = $column_name . ' column-' . $column_name . ( 'name' == $column_name ? ' post-title page-title column-title' : '' );
224
225
			$style = '';
226
			if ( in_array( $column_name, $hidden ) ) {
227
				$class .= ' frm_hidden';
228
			}
229
230
			$class        = 'class="' . esc_attr( $class ) . '"';
231
			$data_colname = ' data-colname="' . esc_attr( $column_display_name ) . '"';
232
			$attributes   = $class . $style . $data_colname;
233
234
			switch ( $column_name ) {
235
				case 'cb':
236
					$r .= '<th scope="row" class="check-column">' . $checkbox . '</th>';
237
					break;
238
				case 'id':
239
				case 'form_key':
240
					$val = $item->{$column_name};
241
					break;
242
				case 'name':
243
					$val = $this->get_form_name( $item, $actions, $edit_link, $mode );
244
					$val .= $action_links;
245
246
					break;
247
				case 'created_at':
248
					$date = gmdate( $format, strtotime( $item->created_at ) );
249
					$val  = '<abbr title="' . esc_attr( gmdate( 'Y/m/d g:i:s A', strtotime( $item->created_at ) ) ) . '">' . $date . '</abbr>';
250
					break;
251
				case 'shortcode':
252
					$val = '<input type="text" readonly="readonly" class="frm_select_box" value="' . esc_attr( '[formidable id=' . $item->id . ']' ) . '" /><br/>';
253
					if ( 'excerpt' == $mode ) {
254
						$val .= '<input type="text" readonly="readonly" class="frm_select_box" value="' . esc_attr( '[formidable key=' . $item->form_key . ']' ) . '" />';
255
					}
256
					break;
257
				case 'entries':
258
					if ( isset( $item->options['no_save'] ) && $item->options['no_save'] ) {
259
						$val = FrmAppHelper::icon_by_class(
260
							'frmfont frm_forbid_icon frm_bstooltip',
261
							array(
262
								'title' => __( 'Saving entries is disabled for this form', 'formidable' ),
263
								'echo'  => false,
264
							)
265
						);
266
					} else {
267
						$text = FrmEntry::getRecordCount( $item->id );
268
						$val  = current_user_can( 'frm_view_entries' ) ? '<a href="' . esc_url( admin_url( 'admin.php?page=formidable-entries&form=' . $item->id ) ) . '">' . $text . '</a>' : $text;
269
						unset( $text );
270
					}
271
			}
272
273
			if ( isset( $val ) ) {
274
				$r .= "<td $attributes>";
275
				$r .= $val;
276
				$r .= '</td>';
277
			}
278
			unset( $val );
279
		}
280
		$r .= '</tr>';
281
282
		return $r;
283
	}
284
285
	/**
286
	 * @param string $edit_link
287
	 */
288
	private function get_actions( &$actions, $item, $edit_link ) {
289
		$new_actions = FrmFormsHelper::get_action_links( $item->id, $item );
290
		foreach ( $new_actions as $link => $action ) {
291
			$new_actions[ $link ] = FrmFormsHelper::format_link_html( $action, 'short' );
292
		}
293
294
		if ( 'trash' == $this->status ) {
295
			$actions = $new_actions;
296
297
			return;
298
		}
299
300
		if ( current_user_can( 'frm_edit_forms' ) ) {
301
			$actions['frm_edit']     = '<a href="' . esc_url( $edit_link ) . '">' . __( 'Edit', 'formidable' ) . '</a>';
302
			$actions['frm_settings'] = '<a href="' . esc_url( '?page=formidable&frm_action=settings&id=' . $item->id ) . '">' . __( 'Settings', 'formidable' ) . '</a>';
303
		}
304
305
		$actions         = array_merge( $actions, $new_actions );
306
		$actions['view'] = '<a href="' . esc_url( FrmFormsHelper::get_direct_link( $item->form_key, $item ) ) . '" target="_blank">' . __( 'Preview', 'formidable' ) . '</a>';
307
	}
308
309
	/**
310
	 * @param string $edit_link
311
	 */
312
	private function get_form_name( $item, $actions, $edit_link, $mode = 'list' ) {
313
		$form_name = $item->name;
314
		if ( trim( $form_name ) == '' ) {
315
			$form_name = __( '(no title)', 'formidable' );
316
		}
317
		$form_name = FrmAppHelper::kses( $form_name );
318
		if ( 'excerpt' != $mode ) {
319
			$form_name = FrmAppHelper::truncate( $form_name, 50 );
320
		}
321
322
		$val = '<strong>';
323
		if ( 'trash' == $this->status ) {
324
			$val .= $form_name;
325
		} else {
326
			$val .= '<a href="' . esc_url( isset( $actions['frm_edit'] ) ? $edit_link : FrmFormsHelper::get_direct_link( $item->form_key, $item ) ) . '" class="row-title">' . FrmAppHelper::kses( $form_name ) . '</a> ';
327
		}
328
329
		$this->add_draft_label( $item, $val );
330
		$val .= '</strong>';
331
332
		$this->add_form_description( $item, $val );
333
334
		return $val;
335
	}
336
337
	/**
338
	 * @param string $val
339
	 */
340
	private function add_draft_label( $item, &$val ) {
341
		if ( 'draft' == $item->status && 'draft' != $this->status ) {
342
			$val .= ' - <span class="post-state">' . __( 'Draft', 'formidable' ) . '</span>';
343
		}
344
	}
345
346
	/**
347
	 * @param string $val
348
	 */
349
	private function add_form_description( $item, &$val ) {
350
		global $mode;
351
		if ( 'excerpt' == $mode ) {
352
			$val .= FrmAppHelper::truncate( strip_tags( $item->description ), 50 );
353
		}
354
	}
355
356
	/**
357
	 * @return string
358
	 */
359
	protected function confirm_bulk_delete() {
360
		return __( 'ALL selected forms and their entries will be permanently deleted. Want to proceed?', 'formidable' );
361
	}
362
}
363