Multi-db plugin conlict with Woocomerce

i have some strange error with woocommerce in my multisite.

no matter what i try to do i get every time the same error (only the gateway file change and line code change) when i click on " woocommerce_checkout_place_order button" on cart page.

no matter what payment i select always the same error.
Fatal error: Call to a member function update_status() on a non-object in /home/public_html/wp-content/plugins/woocommerce/includes/gateways/bacs/class-wc-gateway-bacs.php on line 334

in the chrome console i see this error:
http://test.site.com/wp-admin/admin-ajax.php?action=woocommerce_checkout Failed to load resource: the server responded with a status of 500 (Internal Server Error)

but, the strange thing is, if i refresh the page and click again on " woocommerce_checkout_place_order button" the order is created and all seems working.

my multisite using Multi-DB plugin and domain maaping plugin

what i have tried?
* i have disable all plugins.
* i have try to use default theme
* i removed all plugins from mu-plugins folder
* i tried to create new site (in multisite)
* i check that all configuration in woocommerce are fine
* in wp-config i set: define( 'WP_MAX_MEMORY_LIMIT', '256M' );
in php ini i see 256M
* i have deleted woocommerce and installed the plugin again
* i speak with the hosting siteground and they said that this is not server problem

* i tried to disable checkout script:

function so_27023433_disable_checkout_script(){
wp_dequeue_script( 'wc-checkout' );
}
add_action( 'wp_enqueue_scripts', 'so_27023433_disable_checkout_script' );

After long debugging i have install new clean multi site with only Multi-db plugin and Woocommerce plugin.

i have set Multi-db without any problems (this is not my first).

then i just create demo product and try to create new order. guess what? the same problem the same error!

then, i removed the db-config.php and db.php files. activated Woocommerce and create new product.

then i try to create new order and guess what? all working without any problem!

@Sam Any suggestions what this can be and how to fix this?

Thanks in advance

* If the solution will take some time how can i switch back to default wp multisite DB? (i have around 60 sites)?

  • Adam Czajczyk

    Hey Ruslan,

    I hope you're well today and thank you for your question!

    I see you've conducted an entire set of basic test, that's great! Would you also please set this in your wp-config.php file to rise WP memory limit:

    define( 'WP_MEMORY_LIMIT', '256M' );

    Hence the difference between WP_MAX_MEMORY_LIMIT and WP_MEMORY_LIMIT (http://codex.wordpress.org/Editing_wp-config.php#Increasing_memory_allocated_to_PHP).

    That being said there's also a chance that despite the SiteGround's claims there's something wrong with the server configuration. I'm aware of number of issues regarding this hosting provider and ultimately a lot of those turned out to be on their site.

    I'm not saying this is the case though but it's worth knowing :slight_smile: Let me know please if rising memory limit helped and also hopefully @Sam will be able to throw some helpful ideas here too.

    Cheers,
    Adam

  • Adam Czajczyk

    Hey Ruslan!

    I apologize if I confused you. I was asking you to set

    define('WP_MEMORY_LIMIT', '256M')

    instead of

    define('WP_MAX_MEMORY_LIMIT', '256M').

    That's not the same and it's also not the same as php.ini setting. Although the php allows up to 256M to be used by scripts WordPress will only reach the value set by "WP_MEMORY_LIMIT".
    "WP_MAX_MEMORY_LIMIT" is (according to WordPress Codex) used in admin area only. Furthermore, it only operates within boundaries set with "WP_MEMORY_LIMIT".

    But, apart from this, "500 Internal Server Error" is by nature one of the most "undefined" server errors. In case of WordPress it is usually related to either memory overload or server misconfiguration.

    That being said, I'd like to ask you for one more thing. Could you please turn debugging on by adding

    define('WP_DEBUG', true);

    to your wp-config.php file and see if there are any other errors being reported? Could you also take a look at your server's error log? It would be great if you could post it here in case there are indeed any errors.

    Regards,
    Adam

  • Ruslan

    Hi @Adam Czajczyk,

    i have change to:
    define('WP_MAX_MEMORY_LIMIT', '256M').
    the same error

    i have set define('WP_DEBUG', true); and define('WP_DEBUG_LOG', true);

    and the same error i see in "debug.log":
    [08-Jun-2015 08:05:09 UTC] PHP Notice: Trying to get property of non-object in /home/public_html/ecommerce/wp-includes/post.php on line 5721
    [08-Jun-2015 08:05:09 UTC] PHP Fatal error: Call to a member function update_status() on a non-object in /home/public_html/ecommerce/wp-content/plugins/woocommerce/includes/gateways/bacs/class-wc-gateway-bacs.php on line 334

    this error only come when i use Multi-db plugin

          • Ben

            @Jose here's what I know:

            The is a problem in the woocommerce file: includes/class-wc-order-factory.php

            It using the wordpress function get_post() always returning false in the file:

            public function get_order( $the_order = false ) {
                            global $post;
            
                            if ( false === $the_order ) {
                                    $the_order = $post;
                            } elseif ( is_numeric( $the_order ) ) {
                                    $the_order = get_post( $the_order );

            However, while $the_order is equaling a numeric number, get_post always returns false with multidb.

            So I believe the failure is that get_post is not working with multidb.

            What are your thoughts?

          • Ben

            @jose

            for further debugging, I'd like to also point out that get_post($the_order) is being referred to, $the_order is a number coming the value returned from wp_insert_post($post_array, true) where the data in $post_array is something like this:

            {
                 "post_type":"shop_order",
                 "post_status":"wc-pending",
                 "ping_status":"closed",
                 "post_author":1,
                 "post_password":"order_56a4572e41f26","post_title":"Order – Jan 24, 2016 @ 04:46 AM",
                 "post_parent":0,
                 "post_excerpt":""
            }
          • Ben

            Hi @Adam Czajczyk

            Following up on my posts, perhaps you can also notify @Sam and @Tyler Postle on this as this multi-db perhaps is causing other issues.

            I spent alot of time breaking down the issue. From what I can see, multi-db is not properly setting the database to perform the select from.

            In the plugin before get_post I created the following query:

            $test_q = new WP_Query( array( 'p' => $order_id, 'post_type'=> array( 'product', 'product_variation', 'shop_order', 'view-orders', 'shop_coupon') ) );

            Running this query shows me it is making a query to the database table wp_6_posts, but producing zero results

            nor does
            $test_results = $wpdb->get_row($test_q->request);

            HOWEVER if I do:

            global $exdb;
                            $exdb= new wpdb( $wpdb->dbuser, $wpdb->dbpassword, 'wordpress_16', $wpdb->dbhost );
                            $test_q = new WP_Query( array( 'p' => $order_id, 'post_type'=> array( 'product', 'product_variation', 'shop_order', 'view-orders', 'shop_coupon') ) );
                            $test_results = $exdb->get_row($test_q->request);

            $test_results has the data we were looking for! So by me manually setting it to the right database that multi-db created it worked.

            Wondering if @jose could comment on this

            In addition...

            I used PHPMYADMIN to review my database tables, I am noticing a lot rows of data in wp_meta dealing with site_transient (which i know is used in site mapping)

            I am wondering if domain mapping and marketpress are getting messed up because of this same issue. Hate doing all this work..and I am aware you have recently "decommissioned" this plugin...but there are many clients on the hook still using this plugin and would like to not leave people on the hook that are my clients, would love some action on getting this all resolved asap.

            Thanks.

          • Jose

            Hello there @Ben,

            Hope you are doing great.

            This is funny, I was debugging this issue for long hours some months ago when @Ruslan reported the problem, and I found that the problem was related with the transactional query used by WooCommerce in class-wc-checkout.php into the method create_order(), but I couldn't find the root of the problem in that moment.

            Now, when you mentioned the issue I decided to take another look and I finally found the cause of the issue and have a fix for it :slight_smile:

            First, this is a rough overview of the workflow so that you can better understand the issue:

            Before creating the order WooCommerce starts a transaction:
            $wpdb->query( 'START TRANSACTION' );
            Then inserts the order:
            $order = wc_create_order( $order_data );
            And then confirms the DB operations:
            $wpdb->query( 'COMMIT' );
            Finally, it tries (in the same request) to retrieve the order object:
            $the_order = get_post( $the_order );
            Here is where get_post() didn't return anything.
            For some reason, the result of the transaction wasn't available for subsequent queries.

            The explanation is that MultiDB uses not only one connection per DB, but instead two connections per DB: one for read queries and another for write queries.
            The internal logic in the plugin to decide what kind of query -and therefore which DB connection- to use was assigning different values for "START TRANSACTION" and "COMMIT". The first one was executed in the read connection, while the second one was executed in the write connection.

            Of course, the order was created and available in further requests, since the transaction was actually commited at the end of the request when the connection was closed.

            That said, here is the fix:
            In the file ../wp-content/db.php go the the declaration of the method analyze_query(), line 621 aprox, and change this:

            if ( $select_without_from || $transaction_stuff || $set ) {
            				if ( $this->_last_query_data ) {
            	 				return $this->_last_query_data;
            				}
            }

            Into this:

            if ( $select_without_from || $transaction_stuff || $set ) {
            				if ( $this->_last_query_data ) {
            	 				if( $transaction_stuff ){
            	 	 				$this->_last_query_data['query_type'] = 'write';
            	 				}
            					        return $this->_last_query_data;
            				}
            }

            I'm attaching the patched file here as well.

            I am wondering if domain mapping and marketpress are getting messed up because of this same issue.

            As far as I know, none of those plugins are using transactions, so I don't think this issue is related.

            Please let me know if this fix works fine on your end.

            Thanks for posting and give me the chance to look at this one again :slight_smile:

            Cheers,
            José

          • Ben

            Oh boy...i will try that. Just spent the weekend looking for a fix, i just was able to complete a successful transaction by adding to their WC_Order_Factor class with the function get_order with the following hacked code to get it to process:

            global $exdb;
            global $wpdb;
            global $blog_id;
            global $db_servers;
            $hash_value = md5( $blog_id );
            if ( defined( 'DB_SCALING' ) ) {
                                    if ( DB_SCALING == 4096 ) {
                                            $special_ben_formula = substr( $hash_value, 0, 3 );
                                    } elseif ( DB_SCALING == 256 ) {
                                            $special_ben_formula = substr( $hash_value, 0, 2 );
                                    }
                            } else {
                                    $special_ben_formula  =  substr( $hash_value , 0, 1 );
            }
            $database_name_temp =  $db_servers[$special_ben_formula][0]['name'];
            $exdb = new wpdb( $wpdb->dbuser, $wpdb->dbpassword, $database_name_temp, $wpdb->dbhost );
            $poppopy = new WP_Query( array( 'p' => $the_order, 'post_type'=> array( 'product', 'product_variation', 'shop_order', 'view-orders', 'shop_coupon') ) );
            $the_order = $exdb->get_row($poppopy->request);

            Gonna try your more elegant solution right now...

          • Ben

            To replicate the error, have mutli-db installed on a sub blog individually, then on the sub blog, create a product with 2 variations, then select payment type as check (so you can test without costing money) and then you should see the errror 521.

            This is hitting the file: includes/class-wc-order-factory.php

            Then find the line: $the_order = get_post( $the_order );

            This is returning Null which is causing the issue.

            Perhaps you can suggest a more elegant way than my hack for replacing this line.

          • Jose

            Hey Ben,

            I was able to reproduce the original issue reported by Ruslan, and the change pointed above totally fixedd it on my end.

            Are we taking about the same issue here?

            When you confirm the order the ajax call fails and you get the following error:
            Fatal error: Call to a member function update_status() on a non-object in /home/public_html/wp-content/plugins/woocommerce/includes/gateways/bacs/class-wc-gateway-bacs.php on line 334

            Please advise. :slight_smile:

          • Ben

            @jjaureguiberry

            Just coming back to your post, also posted in the github issues area. (https://github.com/wpmudev/multi-db/issues/5)

            My set up is as follows:

            Multi Site, nginx, Multi-DB

            On a SUB blog, having woocommerce set up, and the stripe gateway.

            I've narrowed down two issues to review:

            in the file: includes/class-wc-order-factory.php the function:

            public function get_order( $the_order = false )

            is failing because the multi-db plugin is not select the correct database when attempting to use:

            get_post( $the_order )

            My solution was to modify the get_order function by manually selecting the right databas associated with the blog id and then manually performing the get_post functionality...pain in the butt, however it worked.

            Now another more complicated problem has happened:

            in the file: includes/abstracts/abstract-wc-order.php
            public function set_total()

            Is failing because again I believe the wrong database is being used when the first time attempting to use the wordpress function:
            update_post_meta( $this->id, $key, $amount );

            Of interest, the second time it attempts to perform the actions on those keys it does work.

            Woocommerce is a very popular plugin, any thoughts you might have regarding why this is happening?

            analyze_query(), line 621 aprox might work with the second issue, but wasn't working with the first one. (will try later today)

            Appreciate it, thanks.

            -Ben

          • Ben

            Its standard install of woocommerce with multi-db set up, nothing fancy. Are you not seeing it? I can set up a test box for you if you want to set up from scratch, but would want to private message you.

            As part of my detective work I noticed that an order seemed to be created but that the order data couldn't be grabbed.

            Please review the file:
            https://github.com/woothemes/woocommerce/blob/master/includes/class-wc-order-factory.php

            Line, 32 and 34 weren't grabbing data.
            $the_order = get_post( $the_order );

            So then I manually recreated the choosing of a database based on the blog ID and manually did the sql for get_post.

            to the function get_order, I added the following:

            ///// ben start
                            global $exdb;
                            global $wpdb;
                            global $blog_id;
                            global $db_servers;
                            $hash_value = md5( $blog_id );
                            if ( defined( 'DB_SCALING' ) ) {
                                    if ( DB_SCALING == 4096 ) {
                                            $special_formula = substr( $hash_value, 0, 3 );
                                    } elseif ( DB_SCALING == 256 ) {
                                            $special_formula = substr( $hash_value, 0, 2 );
                                    }
                            } else {
                                    $special_formula  =  substr( $hash_value , 0, 1 );
                            }
                            $database_name_temp =  $db_servers[$special_formula][0]['name'];
                            $exdb = new wpdb( $wpdb->dbuser, $wpdb->dbpassword, $database_name_temp, $wpdb->dbhost );
                            //ben end

            Then I replaced line's 32 and 34 with:

            $the_query = new WP_Query( array( 'p' => $the_order, 'post_type'=> array( 'product', 'product_variation', 'shop_order', 'view-orders', 'shop_coupon') ) );
                                    $the_order = $exdb->get_row($the_query->request);

            That got the checkout to show and perform orders in test mode....and me being an idiot thought it was working...I was wrong.

            In live mode its not working. I place order and woocommerce will respond that the order is less than 50cents...the message is coming from the plugin woocommerce-gateway-stripe (the mike jolly woothemes branded stripe plugin), the error is located here:
            woocommerce-gateway-stripe/includes/class-wc-gateway-stripe.php

            in that file, in the function process_payment (line 435), it attempts to perform a compare:
            if ( $order->order_total * 100 < 50 ) {
            Which fails because $order->order_total is not set...why is it not set. According to the plugin author Mike Jolly the data is not being set properly with the function set_total with the muti-db plugin:

            To review the funciton set_total we go to line 629 in the file:
            https://github.com/woothemes/woocommerce/blob/master/includes/abstracts/abstract-wc-order.php

            In that function there is the line:
            update_post_meta( $this->id, $key, $amount );
            For some reason Mike suspects this isn't working as expected with multi-db.

            What's weird is that if after the user clicks place order the first time, the less than 50 cents error message will occur. Now when the user clicks place order again without leaving that page or making any changes, the order will function properly.

            The previous fix you suggested didn't work on its own or with my code. But you might have been on to something.

            I'm here on standby...getting this fixed is priority number 1. Please let me know what you think.

          • Jose

            I did see the error on my install before.
            And yes, this line was failing to retrieve the order:
            $the_order = get_post( $the_order );
            It wasn't a problem related to a wrong DB, but a wrong connection when starting and commiting the transaction.
            I fully explained it above.

            With the fix posted in this tread, everything works as expected on my end.
            That's why I need you to reproduce the error in a test install where I can see it and debug it.
            I suspect that some of your customizations weren't removed and are conflicting with the fix?

            Could you please answer my question above:

            Also, how do you arrived to the conclusion that it is selecting the wrong DB? where are you looking at? which DB is expected to be selected and which one is being actually selected?

            Thanks in advance,
            José

          • Jose

            I believe that you were able to get the order with your customization because you were creating a new instance of wpdb and that forced the transaction in the previous connection to be commited.

            I'll wait for the info for your test install.

            Please send me the information via contact form :

            - In the subject field add "Attn: Jose”
            - Link back to this thread
            - Include WP admin/network access
            - Include FTP host and credentials.

            On the contact form, select "I have a different question", this ensures it comes through and gets assigned to me.

            Thanks!

          • Ben

            Jose

            With the fix posted in this tread, everything works as expected on my end.
            That's why I need you to reproduce the error in a test install where I can see it and debug it.
            I suspect that some of your customizations weren't removed and are conflicting with the fix?

            Not sure if WPMU Dev e-mails are going through to you, but the server is now fully set up completely dedicated to getting this fixed.

            Apache/Mysql/Ubuntu
            Clean Latest Wordpress VersiAaron
            WooCommerce Latest version
            WooCommerce Stripe Gateway latest version
            0 other plugins
            wordpress default installed theme
            Wordpress Network Set up

            Not being logged in, Works without issue without multi-db enabled on a sub-site with stripe test keys.

            After converting the site to multi-db and when trying to complete an order with stripe test keys and not being logged in, the issue is replicated that is occurring on my live set up. 521 error.

            I have made no changes to Woo Commerce or multi-db with the exception Jose code suggestion. To my best ability, this is a completely barebones clean install.

            Here is a link to 50 cent product to try testing with:

            http://45.55.4.210/testsite/product/test-product/

            I've also tried the code you suggested by modifying the db.php file and inserting the following code around line 624:

            if( $transaction_stuff ){
                 $this->_last_query_data['query_type'] = 'write';
            }

            However still getting the error. If you are getting this to work, obviously I missing a step here.

            Aaron Jose

            Or anybody else that has experience with the development of multi-db, would appreciate help getting this to work.

            Thanks.

    • Ben

      @jjaureguiberry

      They should give you a raise, because you get shit done.

      They should give me a raise, because I repeatedly find the errors that wpmu dev doesn't believe exist repeatedly. (pro-sites, marketpress, upfront, mass email sender, domain mapping)

      Tested on the production server and now issues with Woo Commerce seem to be resolved and my workarounds are no longer needed.

      Good job Jose, well done! If I were in your country I would buy you dinner.

      Now that you understand this bug, do you think it could be the culprit to the issues affecting other wpmudev plugins (ie marketpress issues were never resolved hence why i needed to move to woocommerce)?

      -Ben

      • Jose

        Ben,

        I'll talk about your raise with the boss :wink:

        Now that you understand this bug, do you think it could be the culprit to the issues affecting other wpmudev plugins (ie marketpress issues were never resolved hence why i needed to move to woocommerce)?

        No, this issue only affects transactions and we don't use it in Marketpress. We don't use transactions in any of our plugins actually.

        I'll be releasing this fix and also pushing the changes to github repo in the short term.

        Thanks a bunch for all your cooperation and for the feedback!

        Cheers,
        José

          • Adam Czajczyk

            Hello Rob,

            I hope you're well today and thank you for your question!

            The last update to Multi-DB plugin was released on March 11th 2015, the same day Jose pushed the fix to Ben's site.

            All the available fixes were included in that release and it was the last update to the plugin ever. Multi-DB plugin is a decommissioned plugin since then, meaning that it's no longer developed and supported and we do not recommend using it. Take a look here please:

            https://premium.wpmudev.org/project/multi-db/

            What Can I Expect From A Decommissioned Plugin?

            This is basically an ‘as-is’ offer. Decommissioned plugins remain available, but no longer receive updates or guaranteed support from our staff. We will, however, continue support for pre-existing users, usage documentation will remain available and you can always search the support ticket archives for questions about Multi-DB, answered by our support team.

            Multi-DB is a complex plugin and should only be used by advanced users familiar with server configuration.

            That said, do you have this plugin implemented on any website already? I'm asking because I cannot see any trace of it being installed in your account history. If you're planning to implement it, I'd strongly advise against it. In case it's necessary, you may ask for professional help on our "Jobs & Pros" job board here:

            https://premium.wpmudev.org/wordpress-development/

            Best regards,
            Adam

    • Adam Czajczyk

      Hello Rob!

      Actually... you're right! That was my mistake, I'm sorry for causing a confusion!

      That said, what I said about Multi-DB plugin is still true and it's no longer being developed, nor is actively supported. We do still provide limited support for those members that are already using it for a long time, hence my question on whether you already got it installed on any site of yours :slight_smile:

      If you're sure that this particular fix would do the trick for you (or you just want to give it a try to make sure), please confirm and I'll ask Jose directly if he could provide me with either "ready to use" file or a solution description. If it's not exactly the same issue though, I'd suggest starting a separate thread of your own, giving as detailed description on this as possible.

      Best regards,
      Adam

  • Adam Czajczyk

    Hello Rob!

    Thanks for your response, it's all clear now :slight_smile:

    I've got in touch with Jose and asked him to give you a helping hand on this. He's not online currently but I'm sure he'll get back to you as soon as possible. Please note however that his response time may be a bit longer than mine as he deals with quite a lot of complex issues.

    Please keep an eye on this thread and either I or Jose - one of us will get back to you.

    Have a nice day!
    Adam

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.