: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Get subscription status.
* @param array $item Payment item.
private function get_subscription_status( $item ) {
if ( ! in_array( $item['type'], [ 'subscription', 'renewal' ], true ) ) {
if ( $item['type'] === 'subscription' ) {
return $item['subscription_status'];
// For renewals, get subscription status from the parent subscription.
$parent_subscription = ( new Queries() )->get_subscription( $item['subscription_id'] );
return ! empty( $parent_subscription->subscription_status ) ? $parent_subscription->subscription_status : '';
* @param array $item Payment item.
private function get_payment_title( array $item ) {
if ( empty( $item['title'] ) ) {
return ' - ' . $item['title'];
* @param array $item Payment item.
private function get_subscription_status_icon( array $item ) {
if ( empty( $item['subscription_id'] ) ) {
return '<span class="dashicons dashicons-marker"></span>';
* Get formatted amount from item.
* @param array $item Payment item.
private function get_formatted_amount_from_item( $item ) {
if ( empty( $item['total_amount'] ) ) {
return wpforms_format_amount( wpforms_sanitize_amount( $item['total_amount'], $item['currency'] ), true, $item['currency'] );
* Get selectors which will be displayed over the bulk action menu.
protected function get_views() {
$base = remove_query_arg( [ 'status', 'paged' ] );
$is_trash_view = $this->is_trash_view();
'<a href="%s"%s>%s <span class="count">(%d)</span></a>',
$this->is_current_view( 'all' ) ? ' class="current"' : '',
esc_html__( 'All', 'wpforms-lite' ),
(int) $this->counts['published']
// Iterate through the filterable statuses and add them to the "$views" array.
$views = array_merge( $views, $this->get_views_for_filterable_statuses( $base ) );
/** This filter is documented in \WPForms\Admin\Payments\Views\Overview\Table::display_tablenav(). */
if ( $this->counts['trash'] || $is_trash_view ) {
$views['trash'] = sprintf(
'<a href="%s"%s>%s <span class="count">(%d)</span></a>',
esc_url( add_query_arg( [ 'status' => 'trash' ], $base ) ),
$is_trash_view ? ' class="current"' : '',
esc_html__( 'Trash', 'wpforms-lite' ),
(int) $this->counts['trash']
return array_filter( $views );
* Determine whether it is a passed view.
* @param string $view Current view to validate.
private function is_current_view( $view ) {
// phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
if ( $view === 'trash' && isset( $_GET['status'] ) && $_GET['status'] === self::TRASH ) {
if ( ( $view === 'search' || $view === 'all' ) && Search::is_search() ) {
return ! isset( $_GET['status'] );
if ( ValueValidator::is_valid( $view, 'status' ) && isset( $_GET['status'] ) && $_GET['status'] === $view ) {
if ( $view === 'all' && ! isset( $_GET['status'] ) && ! Search::is_search() ) {
// phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
* Get value provided in search field.
private function get_search_query() {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
return Search::is_search() ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : '';
private function get_search_conditions() {
if ( ! Search::is_search() ) {
'search_where' => $this->get_search_where_key(),
'search_mode' => $this->get_search_mode_key(),
* This function is responsible for determining whether the table items could be displayed.
private function can_prepare_records() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
// phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
if ( isset( $_GET['form_id'] ) && get_post_status( $_GET['form_id'] ) !== 'publish' ) {
wp_safe_redirect( Page::get_url() );
if ( isset( $_GET['status'] ) && $_GET['status'] !== $this->get_valid_status_from_request() ) {
wp_safe_redirect( Page::get_url() );
if ( isset( $_GET['coupon_id'] ) && ! wpforms()->get( 'payment_meta' )->is_valid_meta( 'coupon_id', absint( $_GET['coupon_id'] ) ) ) {
wp_safe_redirect( Page::get_url() );
// Validate the "type," "gateway," and "subscription_status" parameters.
foreach ( [ 'type', 'gateway', 'subscription_status' ] as $column_name ) {
// Leave the loop if the parameter is not set.
if ( empty( $_GET[ $column_name ] ) ) {
foreach ( explode( '|', $_GET[ $column_name ] ) as $value ) {
if ( ! ValueValidator::is_valid( $value, $column_name ) ) {
wp_safe_redirect( Page::get_url() );
// phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
* Display table form's hidden fields.
private function display_hidden_fields() {
<input type="hidden" name="page" value="wpforms-payments">
<input type="hidden" name="paged" value="1">
$this->display_status_hidden_field();
$this->display_order_hidden_fields();
$this->display_coupon_id_hidden_field();
$this->display_form_id_hidden_field();
* Display hidden field with status value.
private function display_status_hidden_field() {
$status = $this->get_valid_status_from_request();
// Bail early if status is not valid.
// Output the hidden field.
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'admin/payments/hidden-field',
* Display hidden fields with order and orderby values.
private function display_order_hidden_fields() {
// phpcs:disable WordPress.Security.NonceVerification.Recommended
foreach ( [ 'orderby', 'order' ] as $param ) {
// Skip if param is not set.
if ( empty( $_GET[ $param ] ) ) {
// Output the hidden field.
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'admin/payments/hidden-field',
'value' => sanitize_text_field( wp_unslash( $_GET[ $param ] ) ),
// phpcs:enable WordPress.Security.NonceVerification.Recommended
* Display hidden field with coupon ID value.
private function display_coupon_id_hidden_field() {
// phpcs:disable WordPress.Security.NonceVerification.Recommended
if ( empty( $_GET['coupon_id'] ) ) {
// Output the hidden field.
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'admin/payments/hidden-field',
'value' => absint( $_GET['coupon_id'] ),
// phpcs:enable WordPress.Security.NonceVerification.Recommended
* Display hidden field with form ID value.
private function display_form_id_hidden_field() {
// phpcs:disable WordPress.Security.NonceVerification.Recommended
if ( empty( $_GET['form_id'] ) ) {
// Output the hidden field.
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'admin/payments/hidden-field',
'value' => absint( $_GET['form_id'] ),
// phpcs:enable WordPress.Security.NonceVerification.Recommended
* Get the coupon name from the coupon info.
* @param string $coupon_info Coupon information.
private function get_coupon_name_by_info( $coupon_info ) {
// Extract the coupon code from the coupon info using regex.
if ( preg_match( '/^(.+)/i', $coupon_info, $coupon_code ) ) {
return Helpers::get_placeholder_na_text();
* Get the filterable statuses views for the overview table.
* @param string $base Base URL for the view links.
private function get_views_for_filterable_statuses( $base ) {
$statuses = ValueValidator::get_allowed_one_time_statuses();
// Remove the "Partially Refunded" status from the views.
unset( $statuses['partrefund'] );
foreach ( $statuses as $status => $label ) {
// Skip if the count is zero and the view is not the current status.
if ( ! $this->counts[ $status ] && ! $this->is_current_view( $status ) ) {
// Add the view link to the $views array with the status as the key.
$views[ $status ] = sprintf(
'<a href="%s"%s>%s <span class="count">(%d)</span></a>',
esc_url( add_query_arg( [ 'status' => $status ], $base ) ),
$this->is_current_view( $status ) ? ' class="current"' : '',
(int) $this->counts[ $status ]