Completed
Branch master (ad2140)
by Stephanie
02:50
created

FrmFormsListHelper   C

Complexity

Total Complexity 68

Size/Duplication

Total Lines 371
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
dl 0
loc 371
rs 5.6756
c 0
b 0
f 0
wmc 68
lcom 1
cbo 6

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B prepare_items() 0 74 6
A no_items() 0 10 2
B get_bulk_actions() 0 19 7
C extra_tablenav() 0 52 8
B get_views() 0 33 5
A pagination() 0 9 2
F single_row() 0 83 20
C get_actions() 0 24 7
B get_form_name() 0 24 5
A add_draft_label() 0 5 3
A add_form_description() 0 6 2

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 function __construct( $args ) {
10
		$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...
11
12
		parent::__construct( $args );
13
	}
14
15
	public function prepare_items() {
16
		global $wpdb, $per_page, $mode;
17
18
		$page = $this->get_pagenum();
19
		$per_page = $this->get_items_per_page( 'formidable_page_formidable_per_page' );
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
20
21
		$mode    = self::get_param( array(
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
22
			'param'   => 'mode',
23
			'default' => 'list',
24
		) );
25
		$orderby = self::get_param( array(
26
			'param'   => 'orderby',
27
			'default' => 'name',
28
		) );
29
		$order   = self::get_param( array(
30
			'param'   => 'order',
31
			'default' => 'ASC',
32
		) );
33
		$start   = self::get_param( array(
34
			'param'   => 'start',
35
			'default' => ( $page - 1 ) * $per_page,
36
		) );
37
38
		$s_query = array(
39
			array(
40
				'or' => 1,
41
				'parent_form_id' => null,
42
				'parent_form_id <' => 1,
43
			),
44
		);
45
		switch ( $this->status ) {
46
		    case 'template':
47
                $s_query['is_template'] = 1;
48
                $s_query['status !'] = 'trash';
49
		        break;
50
		    case 'draft':
51
                $s_query['is_template'] = 0;
52
                $s_query['status'] = 'draft';
53
		        break;
54
		    case 'trash':
55
                $s_query['status'] = 'trash';
56
		        break;
57
		    default:
58
                $s_query['is_template'] = 0;
59
                $s_query['status !'] = 'trash';
60
		        break;
61
		}
62
63
		$s = self::get_param( array(
64
			'param' => 's',
65
			'sanitize' => 'sanitize_text_field',
66
		) );
67
	    if ( $s != '' ) {
68
	        preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $s, $matches);
69
		    $search_terms = array_map('trim', $matches[0]);
70
			foreach ( (array) $search_terms as $term ) {
71
				$s_query[] = array(
72
					'or'               => true,
73
					'name LIKE'        => $term,
74
					'description LIKE' => $term,
75
					'created_at LIKE'  => $term,
76
				);
77
				unset( $term );
78
			}
79
	    }
80
81
		$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...
82
        $total_items = FrmDb::get_count( 'frm_forms', $s_query );
83
84
		$this->set_pagination_args( array(
85
			'total_items' => $total_items,
86
			'per_page' => $per_page,
87
		) );
88
	}
89
90
	public function no_items() {
91
	    if ( 'template' == $this->status ) {
92
			esc_html_e( 'No Templates Found.', 'formidable' );
93
		} else {
94
			esc_html_e( 'No Forms Found.', 'formidable' );
95
			?>
96
			<a href="<?php echo esc_url( admin_url( 'admin.php?page=formidable&frm_action=new' ) ) ?>"><?php esc_html_e( 'Add New', 'formidable' ); ?></a>
97
<?php
98
		}
99
	}
100
101
	public function get_bulk_actions() {
102
	    $actions = array();
103
104
	    if ( 'trash' == $this->status ) {
105
	        if ( current_user_can('frm_edit_forms') ) {
106
	            $actions['bulk_untrash'] = __( 'Restore', 'formidable' );
107
	        }
108
109
	        if ( current_user_can('frm_delete_forms') ) {
110
	            $actions['bulk_delete'] = __( 'Delete Permanently', 'formidable' );
111
	        }
112
	    } else if ( EMPTY_TRASH_DAYS && current_user_can('frm_delete_forms') ) {
113
	        $actions['bulk_trash'] = __( 'Move to Trash', 'formidable' );
114
	    } else if ( current_user_can('frm_delete_forms') ) {
115
	        $actions['bulk_delete'] = __( 'Delete');
116
	    }
117
118
        return $actions;
119
    }
120
121
	public function extra_tablenav( $which ) {
122
        if ( 'top' != $which ) {
123
            return;
124
        }
125
126
        if ( 'trash' == $this->status && current_user_can('frm_delete_forms') ) {
127
?>
128
            <div class="alignleft actions frm_visible_overflow">
129
			<?php submit_button( __( 'Empty Trash' ), 'apply', 'delete_all', false ); ?>
130
            </div>
131
<?php
132
            return;
133
        }
134
135
        if ( 'template' != $this->status ) {
136
            return;
137
        }
138
139
		$where = apply_filters( 'frm_forms_dropdown', array(), '' );
140
		$forms = FrmForm::get_published_forms( $where );
141
142
        $base = admin_url('admin.php?page=formidable&form_type=template');
143
        $args = array(
144
            'frm_action'    => 'duplicate',
145
            'template'      => true,
146
        );
147
148
?>
149
    <div class="alignleft actions frm_visible_overflow">
150
    <div class="dropdown frm_tiny_top_margin">
151
		<a href="#" id="frm-templateDrop" class="frm-dropdown-toggle button" data-toggle="dropdown"><?php esc_html_e( 'Create New Template', 'formidable' ) ?> <b class="caret"></b></a>
152
		<ul class="frm-dropdown-menu" role="menu" aria-labelledby="frm-templateDrop">
153
		<?php
154
		if ( empty( $forms ) ) {
155
		?>
156
			<li class="frm_dropdown_li"><?php esc_html_e( 'You have not created any forms yet. You must create a form before you can make a template.', 'formidable' ) ?></li>
157
        <?php
158
        } else {
159
            foreach ( $forms as $form ) {
160
				$args['id'] = $form->id;
161
				?>
162
			<li><a href="<?php echo esc_url( add_query_arg( $args, $base ) ); ?>" tabindex="-1"><?php echo esc_html( empty( $form->name ) ? __( '(no title)' ) : FrmAppHelper::truncate( $form->name, 33 ) ); ?></a></li>
163
			<?php
164
			    unset($form);
165
			}
166
        }
167
        ?>
168
		</ul>
169
	</div>
170
	</div>
171
<?php
172
	}
173
174
	public function get_views() {
175
176
		$statuses = array(
177
		    'published' => __( 'My Forms', 'formidable' ),
178
		    'template'  => __( 'Templates', 'formidable' ),
179
		    'draft'     => __( 'Drafts', 'formidable' ),
180
		    'trash'     => __( 'Trash', 'formidable' ),
181
		);
182
183
	    $links = array();
184
	    $counts = FrmForm::get_count();
185
		$form_type = self::get_param( array(
186
			'param' => 'form_type',
187
			'default' => 'published',
188
		) );
189
190
	    foreach ( $statuses as $status => $name ) {
191
192
	        if ( $status == $form_type ) {
193
    			$class = ' class="current"';
194
    		} else {
195
    		    $class = '';
196
    		}
197
198
    		if ( $counts->{$status} || 'published' == $status ) {
199
				$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>';
200
		    }
201
202
		    unset($status, $name);
203
	    }
204
205
		return $links;
206
	}
207
208
	public function pagination( $which ) {
209
		global $mode;
210
211
		parent::pagination( $which );
212
213
		if ( 'top' == $which ) {
214
			$this->view_switcher( $mode );
215
		}
216
	}
217
218
	public function single_row( $item, $style = '' ) {
219
	    global $frm_vars, $mode;
220
221
		// Set up the hover actions for this user
222
		$actions = array();
223
		$edit_link = '?page=formidable&frm_action=edit&id=' . $item->id;
224
225
		$this->get_actions( $actions, $item, $edit_link );
226
227
        $action_links = $this->row_actions( $actions );
228
229
		// Set up the checkbox ( because the user is editable, otherwise its empty )
230
		$checkbox = '<input type="checkbox" name="item-action[]" id="cb-item-action-' . absint( $item->id ) . '" value="' . esc_attr( $item->id ) . '" />';
231
232
		$r = '<tr id="item-action-' . absint( $item->id ) . '"' . $style . '>';
233
234
		list( $columns, $hidden ) = $this->get_column_info();
235
236
        $format = 'Y/m/d';
237
        if ( 'list' != $mode ) {
238
            $format .= ' \<\b\r \/\> g:i:s a';
239
		}
240
241
		foreach ( $columns as $column_name => $column_display_name ) {
242
			$class = $column_name . ' column-' . $column_name . ( 'name' == $column_name ? ' post-title page-title column-title' : '' );
243
244
			$style = '';
245
			if ( in_array( $column_name, $hidden ) ) {
246
                $class .= ' frm_hidden';
247
			}
248
249
			$class = 'class="' . esc_attr( $class ) . '"';
250
			$data_colname = ' data-colname="' . esc_attr( $column_display_name ) . '"';
251
			$attributes = $class . $style . $data_colname;
252
253
			switch ( $column_name ) {
254
				case 'cb':
255
					$r .= '<th scope="row" class="check-column">' . $checkbox . '</th>';
256
					break;
257
				case 'id':
258
				case 'form_key':
259
				    $val = $item->{$column_name};
260
				    break;
261
				case 'name':
262
				    $val = $this->get_form_name( $item, $actions, $edit_link, $mode );
263
			        $val .= $action_links;
264
265
				    break;
266
				case 'created_at':
267
				    $date = date($format, strtotime($item->created_at));
268
					$val = '<abbr title="' . esc_attr( date( 'Y/m/d g:i:s A', strtotime( $item->created_at ) ) ) . '">' . $date . '</abbr>';
269
					break;
270
				case 'shortcode':
271
					$val = '<input type="text" readonly="readonly" class="frm_select_box" value="' . esc_attr( '[formidable id=' . $item->id . ']' ) . '" /><br/>';
272
				    if ( 'excerpt' == $mode ) {
273
						$val .= '<input type="text" readonly="readonly" class="frm_select_box" value="' . esc_attr( '[formidable key=' . $item->form_key . ']' ) . '" />';
274
				    }
275
			        break;
276
			    case 'entries':
277
					if ( isset( $item->options['no_save'] ) && $item->options['no_save'] ) {
278
						$val = '<i class="frm_icon_font frm_forbid_icon frm_bstooltip" title="' . esc_attr('Saving entries is disabled for this form', 'formidable' ) . '"></i>';
279
			        } else {
280
			            $text = FrmEntry::getRecordCount($item->id);
281
						$val = current_user_can('frm_view_entries') ? '<a href="' . esc_url( admin_url( 'admin.php?page=formidable-entries&form=' . $item->id ) ) . '">' . $text . '</a>' : $text;
282
                        unset($text);
283
                    }
284
			        break;
285
                case 'type':
286
                    $val = ( $item->is_template && $item->default_template ) ? __( 'Default', 'formidable' ) : __( 'Custom', 'formidable' );
287
                    break;
288
			}
289
290
			if ( isset($val) ) {
291
			    $r .= "<td $attributes>";
292
			    $r .= $val;
293
			    $r .= '</td>';
294
			}
295
			unset($val);
296
		}
297
		$r .= '</tr>';
298
299
		return $r;
300
	}
301
302
    /**
303
     * @param string $edit_link
304
     */
305
	private function get_actions( &$actions, $item, $edit_link ) {
306
		$new_actions = FrmFormsHelper::get_action_links( $item->id, $item );
307
		foreach ( $new_actions as $link => $action ) {
308
			$new_actions[ $link ] = FrmFormsHelper::format_link_html( $action, 'short' );
309
		}
310
311
		if ( 'trash' == $this->status ) {
312
			$actions = $new_actions;
313
			return;
314
		}
315
316
		if ( current_user_can('frm_edit_forms') ) {
317
			if ( ! $item->is_template || ! $item->default_template ) {
318
				$actions['frm_edit'] = '<a href="' . esc_url( $edit_link ) . '">' . __( 'Edit' ) . '</a>';
319
			}
320
321
			if ( ! $item->is_template ) {
322
				$actions['frm_settings'] = '<a href="' . esc_url( '?page=formidable&frm_action=settings&id=' . $item->id ) . '">' . __( 'Settings', 'formidable' ) . '</a>';
323
			}
324
		}
325
326
		$actions = array_merge( $actions, $new_actions );
327
		$actions['view'] = '<a href="' . esc_url( FrmFormsHelper::get_direct_link( $item->form_key, $item ) ) . '" target="_blank">' . __( 'Preview') . '</a>';
328
    }
329
330
    /**
331
     * @param string $edit_link
332
     */
333
	private function get_form_name( $item, $actions, $edit_link, $mode = 'list' ) {
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
334
        $form_name = $item->name;
335
        if ( trim($form_name) == '' ) {
336
            $form_name = __( '(no title)');
337
        }
338
		$form_name = FrmAppHelper::kses( $form_name );
339
		if ( 'excerpt' != $mode ) {
340
			$form_name = FrmAppHelper::truncate( $form_name, 50 );
341
		}
342
343
        $val = '<strong>';
344
        if ( 'trash' == $this->status ) {
345
            $val .= $form_name;
346
        } else {
347
			$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> ';
348
        }
349
350
        $this->add_draft_label( $item, $val );
351
        $val .= '</strong>';
352
353
        $this->add_form_description( $item, $val );
354
355
        return $val;
356
    }
357
358
    /**
359
     * @param string $val
360
     */
361
    private function add_draft_label( $item, &$val ) {
362
        if ( 'draft' == $item->status && 'draft' != $this->status ) {
363
			$val .= ' - <span class="post-state">' . __( 'Draft', 'formidable' ) . '</span>';
364
        }
365
    }
366
367
    /**
368
     * @param string $val
369
     */
370
    private function add_form_description( $item, &$val ) {
371
        global $mode;
372
        if ( 'excerpt' == $mode ) {
373
            $val .= FrmAppHelper::truncate(strip_tags($item->description), 50);
374
        }
375
    }
376
}
377