: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
if ( empty( $this->views[ $slug ] ) ) {
$view = $this->views[ $slug ];
'<a href="%1$s"%2$s>%3$s <span class="count">(%4$d)</span></a>',
$slug === 'all' ? esc_url( $this->base_url ) : esc_url( add_query_arg( $view['get_var'], $view['get_var_value'], $this->base_url ) ),
$this->current_view === $slug ? ' class="current"' : '',
esc_html( $view['title'] ),
empty( $this->count[ $slug ] ) ? 0 : absint( $this->count[ $slug ] )
* Row actions for views "All", "Forms", "Templates".
* @param array $row_actions Row actions.
* @param WP_Post $form Form object.
public function row_actions_all( $row_actions, $form ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
// Modify row actions only for these views.
$allowed_views = [ 'all', 'forms', 'templates' ];
if ( ! in_array( $this->current_view, $allowed_views, true ) ) {
$is_form_template = wpforms_is_form_template( $form );
if ( wpforms_current_user_can( 'edit_form_single', $form->ID ) ) {
$row_actions['edit'] = sprintf(
'<a href="%s" title="%s">%s</a>',
admin_url( 'admin.php?page=wpforms-builder' )
$is_form_template ? esc_attr__( 'Edit this template', 'wpforms-lite' ) : esc_attr__( 'Edit this form', 'wpforms-lite' ),
esc_html__( 'Edit', 'wpforms-lite' )
if ( wpforms_current_user_can( 'view_entries_form_single', $form->ID ) ) {
$row_actions['entries'] = sprintf(
'<a href="%s" title="%s">%s</a>',
admin_url( 'admin.php?page=wpforms-entries' )
esc_attr__( 'View entries', 'wpforms-lite' ),
esc_html__( 'Entries', 'wpforms-lite' )
wpforms_current_user_can( wpforms_get_capability_manage_options(), $form->ID ) &&
wpforms()->get( 'payment' )->get_by( 'form_id', $form->ID )
$row_actions['payments'] = sprintf(
'<a href="%s" title="%s">%s</a>',
'page' => 'wpforms-payments',
esc_attr__( 'View payments', 'wpforms-lite' ),
esc_html__( 'Payments', 'wpforms-lite' )
if ( wpforms_current_user_can( 'view_form_single', $form->ID ) ) {
$row_actions['preview_'] = sprintf(
'<a href="%s" title="%s" target="_blank" rel="noopener noreferrer">%s</a>',
esc_url( wpforms_get_form_preview_url( $form->ID ) ),
esc_attr__( 'View preview', 'wpforms-lite' ),
esc_html__( 'Preview', 'wpforms-lite' )
if ( wpforms_current_user_can( 'create_forms' ) && wpforms_current_user_can( 'view_form_single', $form->ID ) ) {
$row_actions['duplicate'] = sprintf(
'<a href="%1$s" title="%2$s" data-type="%3$s">%4$s</a>',
'wpforms_duplicate_form_nonce'
$is_form_template ? esc_attr__( 'Duplicate this template', 'wpforms-lite' ) : esc_attr__( 'Duplicate this form', 'wpforms-lite' ),
$is_form_template ? 'template' : 'form',
esc_html__( 'Duplicate', 'wpforms-lite' )
if ( wpforms_current_user_can( 'delete_form_single', $form->ID ) ) {
if ( $this->current_view !== 'all' ) {
$query_arg['type'] = $this->current_view === 'templates' ? 'wpforms-template' : 'wpforms';
$row_actions['trash'] = sprintf(
'<a href="%s" title="%s">%s</a>',
add_query_arg( $query_arg, $this->base_url ),
'wpforms_trash_form_nonce'
$is_form_template ? esc_attr__( 'Move this form template to trash', 'wpforms-lite' ) : esc_attr__( 'Move this form to trash', 'wpforms-lite' ),
esc_html__( 'Trash', 'wpforms-lite' )
* Row actions for view "Trash".
* @param array $row_actions Row actions.
* @param WP_Post $form Form object.
public function row_actions_trash( $row_actions, $form ) {
$this->current_view !== 'trash' ||
! wpforms_current_user_can( 'delete_form_single', $form->ID )
$is_form_template = wpforms_is_form_template( $form );
$row_actions['restore'] = sprintf(
'<a href="%s" title="%s">%s</a>',
'wpforms_restore_form_nonce'
$is_form_template ? esc_attr__( 'Restore this template', 'wpforms-lite' ) : esc_attr__( 'Restore this form', 'wpforms-lite' ),
esc_html__( 'Restore', 'wpforms-lite' )
$row_actions['delete'] = sprintf(
'<a href="%s" title="%s">%s</a>',
'wpforms_delete_form_nonce'
$is_form_template ? esc_attr__( 'Delete this template permanently', 'wpforms-lite' ) : esc_attr__( 'Delete this form permanently', 'wpforms-lite' ),
esc_html__( 'Delete Permanently', 'wpforms-lite' )
* @param string $message Search reset block message.
* @param string $search_term Search term.
* @param array $count Count forms in different views.
* @param string $current_view Current view.
public function search_reset_message( $message, $search_term, $count, $current_view ) {
if ( $current_view !== 'trash' ) {
$count['trash'] = ! empty( $count['trash'] ) ? $count['trash'] : 0;
wp_kses( /* translators: %1$d - number of forms found in the trash, %2$s - search term. */
'Found <strong>%1$d form</strong> in <em>the trash</em> containing <em>"%2$s"</em>',
'Found <strong>%1$d forms</strong> in <em>the trash</em> containing <em>"%2$s"</em>',
* Extra controls to be displayed between bulk actions and pagination.
* @param string $which The location of the table navigation: 'top' or 'bottom'.
public function extra_tablenav( $which ) {
if ( ! wpforms_current_user_can( 'delete_form_single' ) ) {
if ( $this->current_view !== 'trash' ) {
// Preserve current view after applying bulk action.
echo '<input type="hidden" name="status" value="trash">';
// Display Empty Trash button.
'<a href="%1$s" class="button delete-all">%2$s</a>',
'action' => 'empty_trash',
'form_id' => 1, // Technically, `empty_trash` is one of the bulk actions, therefore we need to provide fake form_id to proceed.
'wpforms_empty_trash_form_nonce'
esc_html__( 'Empty Trash', 'wpforms-lite' )