Home > Blockchain >  How to make changes to a column in WooCommerce admin orders list without modifying the core file
How to make changes to a column in WooCommerce admin orders list without modifying the core file

Time:07-07

Before asking this question I noticed that there are other similar questions on Stack Overflow without an accepted answer. Although each issue has a different context, I believe there is something in common.

I found these questions but they didn't help:

  1. Overriding WooCommerce function in includes folder

  2. Override woocommerce files from includes folder

  3. How to override a function in Woocommerce WC_Order_Data_Store_CPT Class

I need to make some changes to the WooCommerce core file, but I don't want to touch the original files. So is there a way to override the functions of the files located in the includes folder?

Specifically, the file is this:

https://woocommerce.github.io/code-reference/files/woocommerce-includes-admin-list-tables-class-wc-admin-list-table-orders.html

I need to modify this piece of code (lines 235 and 237), the match would be the last two printf. My question is if this piece of code can be modified with some filter or functions in functions.php file, so if WooCommerce updates I don't lose the changes.

/**
 * Render columm: order_status.
 */
protected function render_order_status_column() {
    $tooltip                 = '';
    $comment_count           = get_comment_count( $this->object->get_id() );
    $approved_comments_count = absint( $comment_count['approved'] );

    if ( $approved_comments_count ) {
        $latest_notes = wc_get_order_notes(
            array(
                'order_id' => $this->object->get_id(),
                'limit'    => 1,
                'orderby'  => 'date_created_gmt',
            )
        );

        $latest_note = current( $latest_notes );

        if ( isset( $latest_note->content ) && 1 === $approved_comments_count ) {
            $tooltip = wc_sanitize_tooltip( $latest_note->content );
        } elseif ( isset( $latest_note->content ) ) {
            /* translators: %d: notes count */
            $tooltip = wc_sanitize_tooltip( $latest_note->content . '<br/><small style="display:block">' . sprintf( _n( 'Plus %d other note', 'Plus %d other notes', ( $approved_comments_count - 1 ), 'woocommerce' ), $approved_comments_count - 1 ) . '</small>' );
        } else {
            /* translators: %d: notes count */
            $tooltip = wc_sanitize_tooltip( sprintf( _n( '%d note', '%d notes', $approved_comments_count, 'woocommerce' ), $approved_comments_count ) );
        }
    }

    if ( $tooltip ) {
        printf( '<mark  data-tip="%s"><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $this->object->get_status() ) ), wp_kses_post( $tooltip ), esc_html( wc_get_order_status_name( $this->object->get_status() ) ) );
    } else {
        printf( '<mark ><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $this->object->get_status() ) ), esc_html( wc_get_order_status_name( $this->object->get_status() ) ) );
    }
}

CodePudding user response:

What you can do is remove the original order-status column, and then add a new custom order-status column in the same location:

function filter_manage_edit_shop_order_columns( $columns ) {
    // Loop trough existing columns
    foreach ( $columns as $key => $name ) {
        // NOT equal
        if ( $key !== 'order_status' ) {        
            $new_columns[$key] = $name;
        } else {
            // Replace with custom column
            $new_columns['my_order_status'] = __( 'Status', 'woocommerce' );
        }
    }

    return $new_columns;
}
add_filter( 'manage_edit-shop_order_columns', 'filter_manage_edit_shop_order_columns', 10, 1 );

Then you take over the existing code, and adjust it where desired:

function action_manage_shop_order_posts_custom_column( $column, $post_id ) {
    // Get order
    $order = wc_get_order( $post_id );
    
    /**
     * Render columm: order_status.
     */
    if ( $column == 'my_order_status' ) {
        $tooltip                 = '';
        $comment_count           = get_comment_count( $order->get_id() );
        $approved_comments_count = absint( $comment_count['approved'] );

        if ( $approved_comments_count ) {
            $latest_notes = wc_get_order_notes(
                array(
                    'order_id' => $order->get_id(),
                    'limit'    => 1,
                    'orderby'  => 'date_created_gmt',
                )
            );

            $latest_note = current( $latest_notes );

            if ( isset( $latest_note->content ) && 1 === $approved_comments_count ) {
                $tooltip = wc_sanitize_tooltip( $latest_note->content );
            } elseif ( isset( $latest_note->content ) ) {
                /* translators: %d: notes count */
                $tooltip = wc_sanitize_tooltip( $latest_note->content . '<br/><small style="display:block">' . sprintf( _n( 'Plus %d other note', 'Plus %d other notes', ( $approved_comments_count - 1 ), 'woocommerce' ), $approved_comments_count - 1 ) . '</small>' );
            } else {
                /* translators: %d: notes count */
                $tooltip = wc_sanitize_tooltip( sprintf( _n( '%d note', '%d notes', $approved_comments_count, 'woocommerce' ), $approved_comments_count ) );
            }
        }

        if ( $tooltip ) {
            printf( '<mark  data-tip="%s"><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $order->get_status() ) ), wp_kses_post( $tooltip ), wp_kses( wc_get_order_status_name( $order->get_status() ) ) );
        } else {
            printf( '<mark ><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $order->get_status() ) ), wp_kses( wc_get_order_status_name( $order->get_status() ) ) );
        }
    }
}
add_action( 'manage_shop_order_posts_custom_column' , 'action_manage_shop_order_posts_custom_column', 10, 2 );

CodePudding user response:

For your specific case you can override the whole class, if you look at the source code it starts with:

if ( class_exists( 'WC_Admin_List_Table_Orders', false ) ) {
    return;
}
//rest of the code

That means that when WC loads that .php file if the class already exists it exit and live with your implementation.

This is a good compromise between directly modifying a wc core file and having your chance to edit the code.

Be careful tho, wordpress doesn't offer a real priority system when loading plugins, to have this override have effect you have to include the new file containing your implementation BEFORE wc loading time span.

The best dirty way is to create a plugin called something like "aa-my-wc-override" and make it an easy plugin that just includes a file containing the new WC_Admin_List_Table_Orders class implementation. I suggest this way because Wordpress loads the plugin alphabetically.

Another possibile way, if you just need to edit some HTML, maybe to inject some .js file in the backend that takes care of the needed modification. Maybe using AJAX or pure JS, depending on your needs

  • Related