Fatal Error in class/Offer.php

Report issues with the GPL version or Mods here
Post Reply
Biochao
Posts: 18
Joined: Sat Jan 28, 2012 12:45 am
Contact:

Fatal Error in class/Offer.php

Post by Biochao » Sat Aug 17, 2013 3:06 pm

Hello, some of my members are experiencing this error and I don't know what's causing it. I haven't changed any code around the time it started happening. Could it be a problem in the database?

Code: Select all

Fatal error: Call to a member function getWinners() on a non-object in /home/biochaox/public_html/acbay/class/Offer.php on line 870
Thanks

RWAP
Site Admin
Posts: 748
Joined: Fri Jan 08, 2010 2:23 am
Location: Stoke-on-Trent
Contact:

Re: Fatal Error in class/Offer.php

Post by RWAP » Sat Aug 17, 2013 5:11 pm

That will not be an easy one to track down - it could be an issue with one listing in the database (ie. not a valid offer) - I would run a quick bit of code along the lines of:

Code: Select all

$list = Offer::getListFromDB($this->db,'');
foreach ($list as $v){
$offer = Offer::getInstanceFromDB($this->db, $v['id']);
if (!$offer instanceOf Offer) echo 'Oops - error in '.$v['id'];
}
Add this to one of the pages in the admin backend, so only you can see it.

It could also be an issue in the code - which version of Enuuk are you running and what is the function in class\Offer.php around line 870?

Biochao
Posts: 18
Joined: Sat Jan 28, 2012 12:45 am
Contact:

Re: Fatal Error in class/Offer.php

Post by Biochao » Sat Aug 17, 2013 11:29 pm

I'm using the GPL version, I believe it's version 1.

Putting that code on my test instance using the same database gives this error:

Code: Select all

Catchable fatal error: Argument 1 passed to Offer::getListFromDB() must be an instance of MyPDO, null given, called in /home/biochaox/public_html/beta-acbay/themes/admin/offers.php on line 165 and defined in /home/biochaox/public_html/beta-acbay/class/Offer.php on line 328
The lines around 870 in class/offers.php are:

Code: Select all

    /**
     * Returns offers won by a user
     * @param MyPDO $DB database instance
     *
     * @return string
     */
    static public function getOffersWonBy(MyPDO $DB, User $user)
    {
        //Look for offers where the user placed a bid (this is done this way to include Lot auctions case)
        $offersIds = array();
        $bidsValues = array();
        $bidList = Bid::getListFromDB($DB, ' where bids.userId="'.$user->id.'"');
        if($bidList){
            foreach($bidList as $bid){
                $id = $bid['offerId'];
                $offer = Offer::getInstanceFromDB($DB, $id);
                //check if finally he became a winner
                $winners = $offer->getWinners();
                if($winners){
                    foreach($winners as $w){
                        if($user->id == $w->id){
                            $offersIds[] = $id;
                            $bidsValues[$id][$bid['id']] = $bid['value']; // [] is used for Lot case, when user does several bids in Lot
                        }
                    }
                }
            }
            if($offersIds){
                $offersDB = self::getListFromDB($DB, ' where offers.id in ('.implode(',',$offersIds).')');
                $offers = array();
                if($offersDB){
                    foreach($offersDB as $k=>$v){
                        //adds information about the exact bid/s id that won it
                        foreach($bidsValues[$v['id']] as $bidId=>$bidValue){
                            $offers[] = array_merge($v, array('bidId'=>$bidId, 'bidValue'=>$bidValue));
                        }
                    }
                }
                return $offers;
            }
        }
        return array();
    }
This all started happing on a user's profile page by the way.

RWAP
Site Admin
Posts: 748
Joined: Fri Jan 08, 2010 2:23 am
Location: Stoke-on-Trent
Contact:

Re: Fatal Error in class/Offer.php

Post by RWAP » Sun Aug 18, 2013 3:00 pm

If you are going to put that code in the themes/admin/offers.php file, you need to replace references to $this->db by $DB.

Unfortunately, the GPL version has not been updated for quite some time - however, there is nothing in that extract you have provided which should provide an error.

It looks as though one of the bids refers to a non-existant offer.

You have two options:

1) Identify the bid which has an issue - again place some code in themes/admin/offers.php

Code: Select all

        $bidList = Bid::getListFromDB($DB, '');
        if($bidList){
            foreach($bidList as $bid){
                $id = $bid['offerId'];
                $offer = Offer::getInstanceFromDB($DB, $id);
                if (!$offer instanceOf Offer) echo 'Oops in bid ID - '.$bid['id'].' - Offer ID '.$id.' Does not exist <br />';
            }
        }
2) Ignore the problem by adapting the code in class\Offer.php to read:

Code: Select all

    /**
     * Returns offers won by a user
     * @param MyPDO $DB database instance
     *
     * @return string
     */
    static public function getOffersWonBy(MyPDO $DB, User $user)
    {
        //Look for offers where the user placed a bid (this is done this way to include Lot auctions case)
        $offersIds = array();
        $bidsValues = array();
        $bidList = Bid::getListFromDB($DB, ' where bids.userId="'.$user->id.'"');
        if($bidList){
            foreach($bidList as $bid){
                $id = $bid['offerId'];
                $offer = Offer::getInstanceFromDB($DB, $id);
                //check if finally he became a winner  
                $winners=array();
                if ($offer instanceOf Offer)c$winners = $offer->getWinners();
                if($winners){
                    foreach($winners as $w){
                        if($user->id == $w->id){
                            $offersIds[] = $id;
                            $bidsValues[$id][$bid['id']] = $bid['value']; // [] is used for Lot case, when user does several bids in Lot
                        }
                    }
                }
            }
            if($offersIds){
                $offersDB = self::getListFromDB($DB, ' where offers.id in ('.implode(',',$offersIds).')');
                $offers = array();
                if($offersDB){
                    foreach($offersDB as $k=>$v){
                        //adds information about the exact bid/s id that won it
                        foreach($bidsValues[$v['id']] as $bidId=>$bidValue){
                            $offers[] = array_merge($v, array('bidId'=>$bidId, 'bidValue'=>$bidValue));
                        }
                    }
                }
                return $offers;
            }
        }
        return array();
    }
I would prefer to track down the problematic bid which is causing the issue - it could be a something simple in that specific Offer (like it is missing a payment method) or something else.

Unfortunately, the GPL version has not been updated in line with the main Enuuk program, so there could well be an important bug fix which is missing, although I think it is most likely a problem with your server...

If you are running your site on a shared server then it could well be that it is just not powerful enough - in my experience, most of these sort of errors in the database have occured because the server runs out of memory or stops responding in the middle of writing to the SQL database.

Basically Enuuk is too resource hungry to work reliably on a shared server - you really should look at a dedicated server or a VPS from uk2 - the dedicated ones are good value at the moment.

Biochao
Posts: 18
Joined: Sat Jan 28, 2012 12:45 am
Contact:

Re: Fatal Error in class/Offer.php

Post by Biochao » Thu Aug 22, 2013 7:20 pm

Thank you, I found the bid causing the issue and removed it from the database. I am on a shared server with 512M memory limit. Unfortunately, I can't upgrade at the moment, not enough income from the site yet.

I have over 1300 users and around 150 auctions going all the time, could I disable or remove things to alleviate memory? The auctions going on are all for virtual items using a video game currency, so any real world features like shipping and payment methods could be removed. I've already hidden them from view. Could I safely remove auctions and bids over 30 days old?

RWAP
Site Admin
Posts: 748
Joined: Fri Jan 08, 2010 2:23 am
Location: Stoke-on-Trent
Contact:

Re: Fatal Error in class/Offer.php

Post by RWAP » Thu Aug 22, 2013 9:49 pm

512MB is woefully low for Enuuk - it struggles on servers with 2GB (!) although that is the full version.

What you need to do is to try and reduce the number of SQL calls and the amount of information it fetches - rather than deleting listings older than 30 days (that is one option).

Do a search to check for where Shipping and Payment method classes are called from and comment out these sections of code - if your site is not using them, it is pointless having the SQL code interrogate those tables.

One of the other main culprits of server load is the ajax refresh calls - which update the listings on the homepage (in your case every 60 seconds) - the server code for handling these calls actually fetches a lot of information from the database which is not required - you have to intercept all calls with v=JSON and write your own custom Index.php to handle these - you can then write highly focussed new calls in the Offer Class to handle JSON (and CRON calls just passing the information required).

A little discussion appears at:
viewtopic.php?f=26&t=291

and
viewtopic.php?f=2&t=263

However, I will not divulge the secrets of my own enhanced speed module, for commercial reasons.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest